编写ShellCode前首先要做的是确定获取kernel32基地址的方法,在如今WIN7插手的年代,不得不抛弃以前在XP下通用的获取kernel32基地址的方法,而选择能同时在WIN7下运行的代码,参考文章:http://skypher.com/wiki/index.php/Hacking/Shellcode/kernel32,我们就拥有了兼容WIN7的代码了:(代码中寄存器改了下,所以和链接中的原文不一样了,不要奇怪哦)
代码:
assume fs:nothing xor ecx,ecx mov esi,fs:[030H] ; ESI = &(PEB) ([FS:0x30]) mov esi,[esi+0cH] ; ESI = PEB->Ldr mov esi,[esi+01cH] ; ESI = PEB->Ldr.InInitOrder next_module: mov eax,[esi+08H] ; eax = InInitOrder[X].base_address mov edi,[esi+020H] ; eax = InInitOrder[X].module_name (unicode) mov esi,[esi] ; ESI = InInitOrder[X].flink (next module) cmp [edi+12*2],cl ; modulename[12] == 0 ? JNE next_module ; No: try next module.
代码:
mov esi,eax mov edi,30 assume eax:ptr IMAGE_DOS_HEADER mov ecx,DWORD ptr [eax+edi*2] ; 03cH .e_lfanew,用了点迷惑作用 lea eax,[eax+ecx+2] assume eax:ptr IMAGE_NT_HEADERS add edi,078H-2-30 mov ecx,DWORD ptr [eax+edi] ; 078H .OptionalHeader.DataDirectory.VirtualAddress,用了点迷惑作用 .if ecx add ecx,esi assume ecx:ptr IMAGE_EXPORT_DIRECTORY mov ebx,cGetProcAddress sub ebx,[ecx].nBase shl ebx,2 add ebx,[ecx].AddressOfFunctions add ebx,esi mov ebx,[ebx] ;dec ebx ;API地址故意减去1,让OD无法显示API名称 add ebx,esi ;ebx = "GetProcAddress" address mov dGetProcAddress,ebx @fcall ebx,esi,cLoadLibraryA ;dec eax ;API地址故意减去1,让OD无法显示API名称 mov dLoadLibraryA,eax @fcall ebx,esi,cGetModuleHandleA ;dec eax ;API地址故意减去1,让OD无法显示API名称 mov dGetModuleHandleA,eax
代码:
CALL @F db "这里是字符串",0 pop ...
代码:
settext macro arg,text:VARARG local @name call @F @name: db text,0 @@: ifnb <arg> pop arg endif endm
代码:
settext szMsgName,"MessageBoxA" settext szMsg,"SHELLCODE测试信息框" settext szDllName,"user32" ;下面要用到GetProcAddress & LoadLibraryA & GetModuleHandleA 组合来获取API函数MessageBoxA,并弹出一个信息框 @fcall dGetModuleHandleA,szDllName .if !eax @fcall dLoadLibraryA,szDllName .endif .if eax mov hDLL,eax @fcall dGetProcAddress,hDLL,szMsgName .if eax @fcall eax,0,szMsg,0,0 ;弹出一个信息框 .endif .endif .endif