.386 .model flat,stdcall option casemap:none
include windows.inc includelib kernel32.lib
DlgProc PROTO :DWORD,:DWORD,:DWORD,:DWORD InvokePtr PROTO C :DWORD,:DWORD,:VARARG GetAPIByName PROTO :DWORD,:DWORD InitAPI PROTO :DWORD
include NoImport.inc CTEXT MACRO y:VARARG LOCAL sym CONST segment ifidni <y>,<> sym db 0 else sym db y,0 endif CONST ends exitm <offset sym> ENDM VMP_START MACRO db 0EBh,010h,'VMProtect begin',0 ENDM
VMP_END MACRO db 0EBh,0Eh,'VMProtect end',0 ENDM
.data? hInstance HINSTANCE ? NameBuffer db 32 dup(?) SerialBuffer db 32 dup(?)
.const IDD_KEYGEN equ 1001 IDC_NAME equ 1002 IDC_SERIAL equ 1003 IDC_GENERATE equ 1004 IDC_ABOUT equ 1005 IDC_EXIT equ 1006 ico equ 2001
.code start: invoke InitAPI,[esp] $invoke GetModuleHandle,0 mov hInstance,eax $invoke DialogBoxParam, hInstance, IDD_KEYGEN, 0, addr DlgProc, NULL $invoke ExitProcess,0 DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .if uMsg == WM_INITDIALOG $invoke LoadIcon,hInstance,ico $invoke SendMessage,hWnd,WM_SETICON,1,eax $invoke GetDlgItem,hWnd,IDC_NAME $invoke SetFocus,eax .elseif uMsg == WM_COMMAND mov eax,wParam .if eax==IDC_GENERATE $invoke GetDlgItemText,hWnd,IDC_NAME,addr NameBuffer,32 call Generate $invoke SetDlgItemText,hWnd,IDC_SERIAL,addr SerialBuffer .elseif eax==IDC_ABOUT $invoke MessageBox,NULL,CTEXT(" -== NoImport ==--",13,"-= laomms 2007.7 =-") ,CTEXT("关于"),MB_OK .elseif eax==IDC_EXIT $invoke SendMessage,hWnd,WM_CLOSE,0,0 .endif .elseif uMsg == WM_CLOSE $invoke EndDialog,hWnd,0 .endif xor eax,eax ret DlgProc endp
Generate proc $invoke lstrlen, addr NameBuffer test eax, eax jle NOINPUT mov ecx, eax mov esi, offset NameBuffer mov edi, offset SerialBuffer @@: dec ecx mov dl, BYTE ptr [esi+ecx] mov BYTE ptr[edi], dl inc edi or ecx, ecx ja @b NOINPUT: ret Generate endp InitAPI proc pKernel:DWORD mov eax,pKernel ; 取得返回地址 and eax,0FFFFFF00h add eax,4 ; 搜索 'PE'字符 @@: sub eax,4 cmp dword ptr[eax],00004550h ; 检测 'PE' jnz @B mov ebx,eax ; 取高16位 and ebx,0FFFF0000h ; 获取Imagebase
mov ecx,4 ; API函数个数,定义在DATA中的个数 mov esi,OFFSET FunctionNames ; function names mov edi,OFFSET FunctionADDRs ; function address array @@: invoke GetAPIByName,ebx,[esi] ; 获取kernel32.dll mov [edi],eax ; 保存地址 add edi,4 ; 取数组中的下一个函数,一个函数占用一个DWORD add esi,4 ; 取下一个函数 dec ecx jnz @B $invoke LoadLibrary,ADDR szUser32 ;获取load User32.dll mov ebx,eax mov ecx,10 ;函数个数 mov esi,OFFSET FunctionNames+16 ;4个函数占4个DWORD=16 mov edi,OFFSET FunctionADDRs+16 @@: invoke GetAPIByName,ebx,[esi] mov [edi],eax add edi,4 add esi,4 dec ecx jnz @B
; $invoke LoadLibrary,ADDR szGdi32 ; mov ebx,eax ; mov ecx,2 ; mov esi,OFFSET FunctionNames+68 ; mov edi,OFFSET FunctionADDRs+68 ;@@: ; invoke GetAPIByName,ebx,[esi] ; mov [edi],eax ; add edi,4 ; add esi,4 ; dec ecx ; jnz @B Ret InitAPI EndP GetAPIByName proc uses ebx ecx esi edi pImgBase:DWORD,pName:DWORD LOCAL exportDir:DWORD LOCAL count:DWORD mov eax,pImgBase ; get image base of DLL mov ecx,eax ; save in ecx and eax mov ebx,eax add eax,[eax+3Ch] ; Jump over DOS Header add eax,78h ; Jump to PE Data Directory mov eax,[eax] test eax,eax je @bad add eax,ebx ; add ImgBase to RVA mov edx,[eax.IMAGE_EXPORT_DIRECTORY.AddressOfNames] mov ebx,eax ; add ImgBase to RVA of list of names mov eax,[ebx.IMAGE_EXPORT_DIRECTORY.NumberOfNames] mov count,eax ; get number of functions in DLL ; ebx points to IMAGE_EXPORT_DIRECTORY mov exportDir,ebx ; save it @findname: mov esi,[edx+ecx] ; get RVA of function name mov edi,pName ; address name to search for in edi @@: mov al,[esi+ecx] ; compare each byte cmp al,[edi] ; goto next name in DLL jnz @nextname ; if not matching add esi,1 ; next byte and next.... add edi,1 ; test al,al ; till we reach end jne @B ; of string ; Found the name mov ebx,exportDir ; get export table pointer saved on stack sub edx,[ebx.IMAGE_EXPORT_DIRECTORY.AddressOfNames] ; get index in edx mov eax,[ebx.IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals] add eax,ecx ; add imagebase to get address to ordinals shr edx,1 ; divide by two to get ordinal index movzx eax,word ptr[edx+eax]; get ordinal to use as index to functions mov edx,[ebx.IMAGE_EXPORT_DIRECTORY.AddressOfFunctions] add edx,ecx ; add image base mov eax,[eax*4+edx]; use ordinal as index to get function address add eax,ecx ; add imagebase to RVA to get actual address jmp @done @nextname: add edx,4 ; next function in DLL dec count ; decrment counter jne @findname ; exit if no more functions in DLL @bad: xor eax,eax @done: ret GetAPIByName endp InvokePtr proc C nParams:DWORD,pFunc:DWORD,params:VARARG mov ecx,nParams ; get no. of params test ecx,ecx ; don
|