In fact, the inverse of the article is not appropriate, because there is no reverse what procedures.
In http://www.exploit-db.com/exploits/28996/see such a section of the simplest shellcode, the technology is also more common, 0day that book also mentions, the great God all use rotten. But think for a long time did not touch the assembly, on the whim, the right to brush up a bit.
/*User32-free Messagebox Shellcode for any Windows version======================================================== Title:user32-free Messagebox Shellcode for any Windows versionrelease Date:16/10/2013author:giusepp E D ' amore (http://it.linkedin.com/pub/giuseppe-d-amore/69/37/66b) size:113 byte (NULL free) tested ON:WIN8,WIN7,WINVISTA,WINXP,WIN2KPRO,WIN2K8,WIN2K8R2,WIN2K3*/ Char shellcode[] ="\x31\xd2\xb2\x30\x64\x8b\x12\x8b\x52\x0c\x8b\x52\x1c\x8b\x42""\x08\x8b\x72\x20\x8b\x12\x80\x7e\x0c\x33\x75\xf2\x89\xc7\x03""\x78\x3c\x8b\x57\x78\x01\xc2\x8b\x7a\x20\x01\xc7\x31\xed\x8b""\x34\xaf\x01\xc6\x45\x81\x3e\x46\x61\x74\x61\x75\xf2\x81\x7e""\x08\x45\x78\x69\x74\x75\xe9\x8b\x7a\x24\x01\xc7\x66\x8b\x2c "" \x6f\x8b\x7a\x1c\ X01\xc7\x8b\x7c\xaf\xfc\x01\xc7\x68\x79\x74 "" \x65\x01\x68\x6b\x65\x6e\x42\x68\x40\x42\x72\x6f\x89\xe1\xfe " "\x49\x0b\x31\xc0\x51\x50\xff\xd7" ; int Main (int argc, char **ARGV) {int (*f) (); f = (int (*) ()) Shellcode; (int) (*f) ();
After running, a window pops up:
The first reaction is the use of the MessageBox, with WinDbg hang a bit, incredibly several versions of the MessageBox have not broken down, carefully think about, this console program does not load User32.dll, how can call the MessageBox? So I analyzed the
Here is the Shellcode disassembly code that you see after loading it into VS2005, with the following comments:
/*00417000 D2 xor Edx,edx//edx = 0s00417002 B2 for mov dl, 30h//edx = 0x3000417004 8B mov edx,dword ptr fs:[edx]//edx = PEB0 0417007 8B 0C mov edx,dword ptr [edx+0ch]//edx = _peb_ldr_data0041700a 8B 1C mov Edx,dword ptr [edx+1ch]//edx = ininitializationordermodulelist.flink0041700d 8B mov Eax,dword ptr [edx+8]//eax = _ldr_data_table_entry. DllBase00417010 8B mov esi,dword ptr [edx+20h]//esi = _ldr_data_table_entry. basedllname.buffer00417013 8B mov edx,dword ptr [edx]//edx = _ldr_data_table_entry. ininitializationorderlinks.flink00417015 7E 0C cmp byte ptr [esi+0ch],33h//search "kernel32.d ll "00417019 F2 jne shellcode+0dh (41700Dh) 0041701B C7 mov Edi,eax//edi = kernel32.dll.DllBase (image_dos_header) 0041701D 3C add edi, DWORD ptr [eax+3ch]//edi = Kernel32.dll.IMAGE_NT_HEADERS (kernel32.dll.DllBase + image_dos_header.e_lfanew) 0041702 0 8B for mov edx,dword ptr [edi+78h]//edx = kernel32.dll.datadirectory[image_directory_entry_ex PORT]. Virtualaddress (RVA) 00417023 C2 add edx,eax//edx = kernel32.dll.DllBase + K Ernel32.dll.datadirectory[image_directory_entry_export]. Virtualaddress (Real Address) 00417025 8B 7A mov edi,dword ptr [edx+20h]//edi = Kernel32.dll.IM Age_export_directory. Addressofnames (RVA) 00417028 C7 add edi,eax//edi = kernel32.dll.DllBase + K Ernel32.dll.IMAGE_EXPORT_DIRECTORY. Addressofnames (Real Address) 0041702A ED xor ebp,ebp//ebp = 00041702C 8B 34 AF mov esi, DWORD ptr [edi+ebp*4]//esi = Kernel32.dll.IMAGE_EXPORT_DIRECTORY. ADDRESSOFNAMES[EBP] (RVA) 0041702F C6 add esi,eax//esi = Kernel32.dll.DllBas E + Kernel32.dll.IMAGE_EXPORT_DIRECTORY. ADDRESSOFNAMES[EBP] (Real Address) 00417031 Inc EBP//ebp++00417032 81 3E, esi],61746146h,//match, CMP dword ptr [Fata] 00417038-F2 jne shellcode+ 2Ch (41702Ch) 0041703A Bayi 7E (esi+8],74697845h), CMP dword ptr [//match "Exit" 00417041 E9 Jne shellcode+2ch (41702Ch) 00417043 8B 7A mov edi,dword ptr [edx+24h]//edi = Kerne L32.dll.IMAGE_EXPORT_DIRECTORY. Addressofnameordinals (RVA) 00417046 C7 add edi,eax//edi = Kernel32.dll.DllB ASE + Kernel32.dll.IMAGE_EXPORT_DIRECTORY. Addressofnameordinals (RVA) (Real Address) 00417048 8B 2C 6F mov bp, Word ptr [edi+ebp*2]//ebp = Kernel32.dll.IMAGE_EXPORT_DIRECTORY. addressofnameordinals[ebp]0041704c 8B 7A 1C mov edi,dword ptr [edx+1ch]//edi = Kernel32.dll.IMAGE _export_directory. Addressoffunctions (RVA) 0041704F C7 add edi,eax//edi = kernel32.dll.DllBase + Kernel32.dll.IMAGE_EXPORT_DIRECTORY. Addressoffunctions (Real Address) 00417051 8B 7C AF FC mov edi,dword ptr [edi+ebp*4-4]//edi = kernel32.dl L.image_export_directory. Addressoffunctions[ebp-1] (RVA) 00417055 C7 add edi,eax//edi = Kernel32.dll. Dllbase + Kernel32.dll.IMAGE_EXPORT_DIRECTORY. Addressoffunctions[ebp-1] (Real Address) 00417057 1657479h//push "Bro Kenbyte "0041705C (6B) 6E 426e656bh 00417061, 6F push 6f724220h 00417066 mov Ecx,esp//ecx = "@BroKenbyte. " 00417068 FE 0B Dec byte ptr [ECX+0BH]//set end of ' 0041706B + C0 xo R eax,eax//eax = 00041706D push ecx//lpmess Agetext = ECX = "@BrokenByte" 0041706E push eax//uaction = EAX = 00041 706F FF D7 call EDI//fataappexita (0, "@BrokenByte");*/
The original is called the kernel32 in the Fataappexita this function!
Then write your own code to simulate this program:
voidShellcodefunction () {Ppeb Peb =NULL; Ppeb_ldr_data Ldrdata =NULL; Pldr_data_table_entry Ldrentry =NULL; PVOID modulebase =NULL; Pwchar ModuleName =NULL; PVOID kernel32imagebase =NULL;////Based on FS pointing to the current TEB, get PEB through Teb.processenvironmentblock//__asm{mov eax, DWORD ptr fs:[0x30] mov Peb, eax} ldrdata = peb->LDR; Ldrentry = (pldr_data_table_entry) ((ULONG) Ldrdata->ininitializationordermodulelist.flink-0x10); Modulebase = ldrentry->Dllbase; ModuleName = ldrentry->Basedllname.buffer;while (ldrentry->basedllname.buffer[0x0c/2]! =‘3‘) {ldrentry = (pldr_data_table_entry) ((ULONG) Ldrentry->ininitializationorderlinks.flink-0x10); Modulebase = ldrentry->Dllbase; ModuleName = ldrentry->Basedllname.buffer; } kernel32imagebase =Modulebase;////After locating to Kernel32.dll, start analyzing the import table of the PE filePimage_dos_header Imagedosheader =NULL; Pimage_nt_headers imagentheaders =NULL; Pimage_export_directory imageexportdirectory =NULL; DWORD Index =0; WORD Functionindex =0; char* functionname =NULL; typedefvoid (__stdcall *Pfn_fatalappexit) (UINT, LPCSTR); Pfn_fatalappexit Pfnfatalappexit =NULL; Imagedosheader =(Pimage_dos_header) Kernel32imagebase; Imagentheaders = (pimage_nt_headers) ((pbyte) Imagedosheader + imagedosheader->E_lfanew); Imageexportdirectory = (pimage_export_directory) ((ULONG) Kernel32imagebase + imagentheaders->Optionalheader.datadirectory[image_directory_entry_export]. virtualaddress);while (1{functionname = (char*) ((ULONG) Kernel32imagebase + (((Pulong) ((ULONG) Kernel32imagebase + imageexportdirectory-> Addressofnames)) [index++]));if (strncmp (functionname, "fatalappexita", Span style= "color: #800080;" >12) = = 0break; } Functionindex = ((Pword) ((ULONG) Kernel32imagebase + imageexportdirectory->addressofnameordinals)) [Index-1addressoffunctions)) [Functionindex]); Pfnfatalappexit (0, @ Brokenbyte ");}
It is important to note that this is just a simulation of its C language implementation, not completely reversed. Because this is shellcode, there is no local variable, and the function stack balancing operation is done using registers. In addition, there is no consideration for a lot of exception handling, code rigor is not how
Finally, the process of thinking a lot of places are introduced, then introduce it:
1, FS Register under Ring3 as a segment selector, in the GDT point to a special page-thread environment block TEB.
2, while the TEB in the offset 0x30 point to the owning process of the process environment block PEB.
3, PEB in the offset 0x0c is a pointer, pointing to a peb_ldr_data structure, which contains the current process load module information.
4. There are three list_entry in the peb_ldr_data structure, in which ininitializationordermodulelist is to string all the modules into a linked list in the order of initialization.
5, the above ininitializationordermodulelist link structure is ldr_data_table_entry, this structure is a specific DLL information, including the load base address, size, entry address, name and so on.
6, traverse this list, find kernel32! belongs to the ldr_data_table_entry structure, and then get its load base address saved up.
7, the loading base point is a PE file header beginning of the place, starting from here to the PE file export table analysis, get Fatalappexita function address. About the contents of the PE file, there is not much to say, you can refer to the "Windows PE authoritative guide" this book.
"Reverse chapter" Analysis a simple shellcode--from TEB to function address acquisition