Тема:
Защита программ от трассировки, отладчиков и дизассемблрования.
Предлагаю постить идеи и/или готовые решения.
#Compile Exe
#Include "win32api.inc"
Function PBMain() As Long
On Error Resume Next
Dim hLib As Long, hProc As Long, lRet As Long
Dim sFunc As Asciiz * %MAX_PATH
sFunc = "IsDebuggerPresent"
hLib = LoadLibrary("kernel32.dll")
hProc = GetProcAddress(hLib, sFunc)
! call hProc
! mov lRet, eax
If lRet = 1 Then
MsgBox "Включен отладчик!"
Else
MsgBox "Отладчик не обнаружен"
End If
End Function
#Compile Exe
#Dim All
#Include "win32api.inc"
Function IsDebuggerAttached() As Long
Local vi As OSVERSIONINFO
Local IsWin9x As Long
Local Dw As Dword
Local i As Dword
vi.dwOsVersionInfoSize = SizeOf(vi)
GetVersionEx vi
IsWin9x = ((vi.dwPlatformId = %VER_PLATFORM_WIN32_WINDOWS) And (vi.dwMinorVersion = 0)) Or _
((vi.dwPlatformId = %VER_PLATFORM_WIN32_WINDOWS) And (vi.dwMinorVersion <> 0))
If IsWin9x Then
!push eax '// Preserve the registers
!mov eax, fs:[&h18] '// Get the TIB's linear address
!mov eax, dword ptr [eax + &h20] '// Debugger Contex for Win9x
!mov dword ptr dw, eax '// Save it
!pop eax '// Restore the registers
If Dw Then
Function = -1
Else
Function = 0
End If
Else
!push eax '// Preserve the registers
!push ecx
!mov eax, fs:[&h18] '// Get the TIB's linear address
!mov eax, dword ptr [eax + &h30]
!mov ecx, dword ptr [eax] '// Get the whole DWORD
!mov dword ptr dw, ecx '// Save it
!pop ecx '// Restore the registers
!pop eax
i= dw And &h00010000???
If i Then
Function = -1
Else
Function = 0
End If
End If
End Function
Function PBMain () As Long
If IsDebuggerAttached=-1 Then
MsgBox "Работаем под отладчиком!"
Else
MsgBox "Отладчик не обнаружен"
End If
End Function
Пример обнаружения отладчика через API функцию IsDebuggerPresent, любой средний кракер легко пропатчит такую программу.
keks-n писал(а):Есть. Дампер никогда не задампит kernel-mode хэндлы. Мораль - завяжи работы на них.
#Compile Exe
#Include "win32api.inc"
Global imgSection() As IMAGE_SECTION_HEADER
Function AppExeName() As String
On Error Resume Next
Local buffer As Asciiz * 256
GetModuleFileName GetModuleHandle(ByVal 0&), Buffer, 256
Function = Buffer
End Function
Function FileOffset(RVA As Dword) As Dword
'Convert relative virtual address to file offset
Dim I As Dword, LastEntry As Dword
LastEntry = UBound(imgSection) - 1
For I = 0 To LastEntry
If RVA >= imgSection(i).VirtualAddress Then
If I = LastEntry Then
FoundOffset:
Function = RVA - imgSection(i).VirtualAddress + imgSection(i).PointerToRawData
Else
If RVA < imgSection(i + 1).VirtualAddress Then GoTo FoundOffset
End If
End If
Next I
End Function
Function PBMain() As Long
Local ExeHdrInfo As IMAGE_NT_HEADERS
Local DOSHdr As Image_DOS_Header
Local I As Long, RVA As Dword
Open AppExeName For Binary Access Read Lock Shared As #1
Get #1,, DosHdr
Seek #1, 0
Seek #1, DosHdr.e_lfanew + 1
se% = Seek(#1)
Get #1,, ExeHdrInfo
ReDim imgSection(ExeHdrInfo.FileHeader.NumberOfSections) As IMAGE_SECTION_HEADER
For I = 0 To ExeHdrInfo.FileHeader.NumberOfSections - 1
Get #1, 25 + DosHdr.e_lfanew + ExeHdrInfo.FileHeader.SizeOfOptionalHeader + (40 * I), imgSection(i)
Next I
Close #1
RVA = ExeHdrInfo.OptionalHeader.AddressOfEntryPoint 'the relative virtual address we want to convert
RVA = RVA + ExeHdrInfo.OptionalHeader.ImageBase
Poke RVA, &hC3 'C3 = ret
MsgBox "Hello world!"
End Function
! jmp ret1
! push ret1
! retn
#COMPILE EXE
#INCLUDE "WIN32API.INC"
FUNCTION PBmain as LONG
LOCAL ret1 as LONG
LOCAL ret2 as LONG
LOCAL ret3 as LONG
ret3 = CodePtr(nextLabel)
ret2 = CodePtr(do_that)
ret1 = CodePtr(do_this)
! push ret3
! push ret2
! jmp ret1
NextLabel:
MsgBox "Hi, I am back"
FUNCTION = 0
End FUNCTION
SUB do_this
MsgBox "I am at 'do_this' sub"
END SUB
SUB do_that
MsgBox "I am at 'do_that' sub"
END SUB
$COMPILE EXE "CRYPT.EXE"
FUNCTION PBMAIN() AS LONG
DIM L1 AS DWORD
DIM L2 AS DWORD
DIM L3 AS DWORD
DIM A1 AS STRING
DIM I AS LONG
DIM V AS STRING
OPEN "TEST.EXE" FOR BINARY AS #1
L1 = LOF(1)
GET$ #1, L1, A1
V = CHR$(255) & CHR$(255) & CHR$(0) & CHR$(1) & CHR$(255) & CHR$(255)
L1 = INSTR(A1, V) + 6
L2 = INSTR(L1, A1, V)
L3 = L2 - L1
FOR I = 0 TO L3 - 1
MID$(A1, L1 + I, 1) = CHR$(ASC(MID$(A1, L1 + I, 1)) XOR ASC("T"))
NEXT I
SEEK #1, 1
PUT$ #1, A1
CLOSE #1
EXIT FUNCTION
END FUNCTION
$COMPILE EXE "TEST.EXE"
DECLARE FUNCTION VirtualProtectC LIB "KERNEL32.DLL" ALIAS "VirtualProtect" (BYVAL lpAddress AS DWORD, BYVAL dwSize AS DWORD, BYVAL flNewProtect AS DWORD, BYREF lpflOldProtect AS DWORD) AS DWORD
DECLARE FUNCTION FlushInstructionCacheC LIB "KERNEL32.DLL" ALIAS "FlushInstructionCache" (BYVAL hProcess AS DWORD, BYVAL lpBaseAddress AS DWORD, BYVAL dwSize AS DWORD) AS DWORD
DECLARE FUNCTION GetCurrentProcessC LIB "KERNEL32.DLL" ALIAS "GetCurrentProcess" () AS DWORD
%PAGE_READWRITE = 4&
SUB DecryptCode(L1 AS LONG, L2 AS LONG)
DIM A1 AS STRING
DIM L3 AS DWORD
DIM Mode AS DWORD
DIM Result AS LONG
DIM OrigMode AS DWORD
DIM I AS LONG
DIM Key AS LONG
Key = ASC("T")
L3 = L2 - L1
A1 = PEEK$(L1, L3)
FOR I = 1 TO L3
MID$(A1, I, 1) = CHR$(ASC(MID$(A1, I, 1)) XOR Key)
NEXT I
MODE = %PAGE_READWRITE
Result = VirtualProtectC(L1, L3, MODE, OrigMode)
POKE$ L1, A1
Result = VirtualProtectC(L1, L3, OrigMode, MODE)
Result = FlushInstructionCacheC(GetCurrentProcessC(), L1, L3)
EXIT SUB
END SUB
FUNCTION PBMAIN() AS LONG
CALL DecryptCode(CODEPTR(Label1), CODEPTR(Label2))
GOTO Label1:
! DB 255, 255, 0, 1, 255, 255
Label1:
MSGBOX "Hello"
EXIT FUNCTION
Label2:
! DB 255, 255, 0, 1, 255, 255
END FUNCTION
Хакер писал(а):а потом что он ещё и сильно неправильный.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 23