[转载]Inject your code to a Portable Executable file
<P>翻译作者:天魔降临</P><P>原始链接:[url]http://www.ph4nt0m.org/bbs/showthread.php?s=&threadid=34318[/url]</P>
<P><STRONG>PS:翻译作者话:</STRONG></P>
<P><STRONG>事先声明这片文章并非我的原创,你可以在这个地址</STRONG><A href="http://www.codeproject.com/system/inject2exe.asp" target=_blank><STRONG>[url]http://www.codeproject.com/system/inject2exe.asp[/url]</STRONG></A><STRONG>察看<BR><BR>到原文,由于本人能力有限,可能有一些翻译错误请见谅(PS:感谢ROOTKIT上的朋友告诉我这片文章)</STRONG></P>
<P><STRONG></STRONG></P>
<P><STRONG><FONT color=#eec211>Download </FONT></STRONG></P>
<P><STRONG><BR><A href="http://www.codeproject.com/system/inject2exe/peviewer.zip" target=_blank>PE Viewer</A> <BR><BR><A href="http://www.codeproject.com/system/inject2exe/pemaker1.zip" target=_blank>PE Maker </A>- Step 1 <BR><BR><A href="http://www.codeproject.com/system/inject2exe/pemaker2.zip" target=_blank>PE Maker </A>- Step 2 - Travel towards OEP<BR><BR><A href="http://www.codeproject.com/system/inject2exe/pemaker3.zip" target=_blank>PE Maker </A>- Step 3 - Support Import Table.<BR><BR><A href="http://www.codeproject.com/system/inject2exe/pemaker4.zip" target=_blank>PE Maker </A>- Step 4 - Support DLL and OCX<BR><BR><A href="http://www.codeproject.com/system/inject2exe/pemaker5.zip[/" target=_blank>PE Maker - Step 5 </A>- Final work. <BR><BR><A href="http://www.codeproject.com/system/inject2exe/test1.zip" target=_blank>CALC.EXE </A>- test file<BR><BR>0序文<BR><BR>也许你想要了解一个病毒,注入到程序内部并且感染他的方法,或者你对保护你特殊的PE文件的数据感<BR><BR>兴趣。你能使用这篇文章的源代码构建你自定义的EXE BUILDER。如果用在好的方面,他能教你怎样保<BR><BR>护或封装加密你的PE文件,但是同样如果你用在邪恶的方面,他能产生一个病毒。然而,我写这篇文章<BR><BR>的目的是前者,所以,我不会为不道德的使用负责。<BR><BR>1预备知识 <BR><BR>按照主题这篇文章不需要特殊的预备知识,如果你已经了解了DEBUGGER和文件结构,那么我建议你跳<BR><BR>过2,3部分,这两部分是为毫无基础的人准备的。<BR><BR>2.PE文件的结构 <BR><BR>规定PE文件的结构为WINDOWS OS提供了最好的方式去执行代码,并且储存一个程序运行所需要的基本<BR><BR>数据。例如常量,变量等等。如图:<BR><BR><IMG alt="" src="http://images.blogcn.com/2006/3/4/1/goblinbest,2006030415911.png" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0> <BR><IMG alt="" src="http://images.blogcn.com/2006/3/4/2/goblinbest,20060304263.png" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0> <BR><IMG alt="" src="http://images.blogcn.com/2006/3/4/2/goblinbest,2006030421416.png" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0> <BR><IMG alt="" src="http://images.blogcn.com/2006/3/4/2/goblinbest,200603042163.png" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0> <BR><IMG alt="" src="http://images.blogcn.com/2006/3/4/2/goblinbest,200603042190.png" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0> <BR><BR>2.1MS-DOS的数据 <BR><BR>MS-DOS数据由你的可执行文件调用DOS内部的一个函数完成。并且 the MS-DOS Stub program让他显示:<BR><BR>This program can not be run in MS-DOS mode" 或"This program can be run only in Windows mode的字样,或者<BR><BR>当你试图在 MS-DOS 6.0中运行一个windows文件时也回显示类似的字样。MS-DOS数据最有意思的部分是<BR><BR>"MZ"! <BR><BR>对于我,在 MS-DOS 数据中仅仅PE署名的偏移是重要的,借助于他我能找到WINDOWS NT数据的位置。<BR><BR>我建议你在看看上图。然后看看 <WINNT.H>文件中IMAGE_DOS_HEADER 的结构。<BR><BR><IMG alt="" src="http://images.blogcn.com/2006/3/4/2/goblinbest,2006030424043.png" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0><BR><BR>e_lfanew是一个与WINDOWS NT数据有关的偏移。在这我提供你一个显示EXE文件头信息的工具。<BR><BR>PE Viewer<BR><BR><A href="http://www.codeproject.com/system/inject2exe/peviewer.zip" target=_blank>Download source files - 132 Kb </A><BR><BR>2.2 The Windows NT data<BR><BR>正如前一节提及的e_lfanew储存者有关WINDOWS NT数据位置的信息,假设 pMem 指针与指向一个PE文<BR><BR>件内存空间的起始点时,借助于下面的代码你既能找会DOS 头,也能找到WINDOWS NT 头<BR><BR>Code: </P>
<P>
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>IMAGE_DOS_HEADERimage_dos_header</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>IMAGE_NT_HEADERSimage_nt_headers</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>PCHAR pMem</FONT></FONT><FONT face=新宋体 color=#007700>; <BR></FONT><FONT face=新宋体><FONT color=#0000bb>… <BR>memcpy</FONT><FONT color=#007700>(&</FONT><FONT color=#0000bb>image_dos_header</FONT><FONT color=#007700>, </FONT><FONT color=#0000bb>pMem</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#0000bb>sizeof</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>IMAGE_DOS_HEADER</FONT></FONT><FONT face=新宋体><FONT color=#007700>)); <BR></FONT><FONT color=#0000bb>memcpy</FONT><FONT color=#007700>(&</FONT><FONT color=#0000bb>image_nt_headers</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#0000bb>pMem</FONT><FONT color=#007700>+</FONT><FONT color=#0000bb>image_dos_header</FONT><FONT color=#007700>.</FONT><FONT color=#0000bb>e_lfanew</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#0000bb>sizeof</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>IMAGE_NT_HEADERS</FONT></FONT><FONT face=新宋体 color=#007700>));<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE></P>
<P><BR><BR>似乎找回头信息是很容易的事,我建议去看MSDN中关于<A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/image_nt_headers_str.asp" target=_blank>IMAGE_NT_HEADERS</A> 的说明。现在你应该很了<BR><BR>解WINDOW NT结构了,他包含PE署名,the File Header,和the Optional Header。<BR><BR>下面是大多数环境中IMAGE_NT_HEADERS的结构:<BR><BR><CODE: < P>
<P>
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>PRE lang</FONT></FONT><FONT face=新宋体><FONT color=#007700>=</FONT><FONT color=#0000bb>c</FONT><FONT color=#007700>++></FONT><FONT color=#0000bb>FileHeader</FONT><FONT color=#007700>-></FONT></FONT><FONT face=新宋体><FONT color=#0000bb>NumberOfSections <BR>OptionalHeader</FONT><FONT color=#007700>-></FONT></FONT><FONT face=新宋体><FONT color=#0000bb>AddressOfEntryPoint <BR>OptionalHeader</FONT><FONT color=#007700>-></FONT></FONT><FONT face=新宋体><FONT color=#0000bb>ImageBase <BR>OptionalHeader</FONT><FONT color=#007700>-></FONT></FONT><FONT face=新宋体><FONT color=#0000bb>SectionAlignment <BR>OptionalHeader</FONT><FONT color=#007700>-></FONT></FONT><FONT face=新宋体><FONT color=#0000bb>FileAlignment <BR>OptionalHeader</FONT><FONT color=#007700>-></FONT></FONT><FONT face=新宋体 color=#0000bb>SizeOfImage <BR>OptionalHeader</FONT><FONT face=新宋体><FONT color=#007700>-> <BR></FONT><FONT color=#0000bb>DataDirectory</FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>IMAGE_DIRECTORY_ENTRY_IMPORT</FONT><FONT color=#007700>]-></FONT></FONT><FONT face=新宋体><FONT color=#0000bb>VirtualAddress <BR>OptionalHeader</FONT><FONT color=#007700>-></FONT><FONT color=#0000bb>DataDirectory</FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>IMAGE_DIRECTORY_ENTRY_IMPORT</FONT><FONT color=#007700>]-></FONT><FONT color=#0000bb>Size</FONT><FONT color=#007700></< FONT><FONT color=#0000bb>PRE</FONT></FONT><FONT face=新宋体 color=#007700>><BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></FONT></TD></TR></TBODY></TABLE></P>
<P><BR><BR>你能清晰的观察到,这些值的目的,以及当为一个EXE文件分配虚拟内存时,他们的脚色。<BR><BR>我要对PE数据目录进行一个简单的说明。当你通过Windows NT 信息对Optional header 进行观察时,你会<BR><BR>发现在Optional Header的结尾处有十六个目录,再那你能找到连续的目录,包括一些与虚拟内存和其大小<BR><BR>有关的信息。<BR><BR>Code: </P>
<P>
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR></FONT><FONT face=新宋体 color=#ff8000>#define IMAGE_DIRECTORY_ENTRY_EXPORT0// Export Directory <BR>#define IMAGE_DIRECTORY_ENTRY_IMPORT1// Import Directory <BR>#define IMAGE_DIRECTORY_ENTRY_RESOURCE2// Resource Directory <BR>#define IMAGE_DIRECTORY_ENTRY_EXCEPTION3// Exception Directory <BR>#define IMAGE_DIRECTORY_ENTRY_SECURITY4// Security Directory <BR>#define IMAGE_DIRECTORY_ENTRY_BASERELOC5// Base Relocation Table <BR>#define IMAGE_DIRECTORY_ENTRY_DEBUG6// Debug Directory <BR>#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE7// Architecture Specific Data <BR>#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR8// RVA of GP <BR>#define IMAGE_DIRECTORY_ENTRY_TLS9// TLS Directory <BR>#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG10// Load Configuration Directory <BR>#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT11// Bound Import Directory in headers <BR>#define IMAGE_DIRECTORY_ENTRY_IAT12// Import Address Table <BR>#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT13// Delay Load Import Descriptors <BR>#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14// COM Runtime descriptor<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE></P>
<P><BR><BR>对于我们,如果你想观察相对虚拟内存地址和数据尺寸,下面的代码是足够的:<BR><BR>Code: </P>
<P>
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>DWORD dwRVA </FONT></FONT><FONT face=新宋体><FONT color=#007700>= </FONT><FONT color=#0000bb>image_nt_headers</FONT><FONT color=#007700>.</FONT><FONT color=#0000bb>OptionalHeader</FONT></FONT><FONT face=新宋体><FONT color=#007700>-> <BR></FONT><FONT color=#0000bb>DataDirectory</FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>IMAGE_DIRECTORY_ENTRY_RESOURCE</FONT><FONT color=#007700>]-></FONT><FONT color=#0000bb>VirtualAddress</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORD dwSize </FONT><FONT color=#007700>= </FONT><FONT color=#0000bb>image_nt_headers</FONT><FONT color=#007700>.</FONT><FONT color=#0000bb>OptionalHeader</FONT></FONT><FONT face=新宋体><FONT color=#007700>-> <BR></FONT><FONT color=#0000bb>DataDirectory</FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>IMAGE_DIRECTORY_ENTRY_RESOURCE</FONT><FONT color=#007700>]-></FONT><FONT color=#0000bb>Size</FONT></FONT><FONT face=新宋体 color=#007700>;<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE></P>
<P><BR><BR><B>2.3 The Section Headers and Sections(节头和节)</B> <BR><BR>现在我们观察PE文件怎样声明节的位置和尺寸。为了更好的理解节头(Section header)和节区的特征,我建<BR><BR>议你去看看IMAGE_SECTION_HEADER在MSDN定义的结构,对于一个EXE packer的开发者VirtualSize, <BR><BR>VirtualAddress, SizeOfRawData, PointerToRawData和Characteristics单元有着严格的规则。当开发一个exe <BR><BR>packer,你应该非常了解他们。当你修改他们时,有许多你要注意,你要按OptionalHeader-<BR><BR>>SectionAlignment的顺序小心排列VirtualSize和VirtualAddress同样SizeOfRawData和PointerToRawData要按<BR><BR>OptionalHeader->FileAlignment的顺序排列。否则你将损坏目标EXE文件,并且不能运行他们。至于<BR><BR>Characteristics,更要格外小心,你要按IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | <BR><BR>IMAGE_SCN_CNT_INITIALIZED_DATA的顺序建立一个节区。我更喜欢我的新节区在进程运行时有初始化<BR><BR>这些数据的能力。当然引入表也要如此。此外,我还需要他能利用loader修改他自己。<BR><BR>同样你要考虑好新的节区名,这样你能仅通过名字就知道他们的作用。如表二<BR><BR><B>表二</B> <BR><BR><IMG alt="" src="http://images.blogcn.com/2006/3/5/11/goblinbest,2006030520152.jpg" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0> <BR><BR>为了更好的理解节头和节区,请运行PE viewer。借助于他,你能了解一个文件映像中节头的应用。要想<BR><BR>观察到虚拟内存,你应该用调试器载入一个PE文件。请记住无论什么时候在PE文件中删除或添加节区,<BR><BR>注意调整PE文件的NumberOfSections( IMAGE_NT_HEADERS-> FileHeader-><CODE>NumberOfSections)他说明<BR><BR>了节区的数目。<BR><BR><B>3 DEBUGER、DISASSEMBLER和一些有用的工具</B> <BR><BR><B>3.1 DEBUGER</B> <BR><BR>要想变成一个PE工具的开发者,对BUG跟踪程序的使用经验是一个必备条件。此外,你还不得知道一些<BR><BR>必备的汇编指令,对于我们INTEL公司的文档是最好的参考书,你可以到INTEL的网站获得他们。<BR><BR><A href="http://www.intel.com/design/pentium4/manuals/index_new.htm#1" target=_blank>IA-32 Intel Architecture Software Developer’s Manuals. </A><BR><A href="http://www.intel.com/design/pentium4/manuals/index_new.htm#1" target=_blank>Intel Itanium Architecture Assembly Language Reference Guide. </A><BR><A href="http://www.intel.com/cd/ids/developer/asmo-na/eng/19415.htm" target=_blank>The Intel Itanium Processor Developer Resource Guide. </A><BR>对于PE文件的追踪,我认为SOFTICE是最好的调试工具。借助与内核模式我们可以进行进程追踪而无须<BR><BR>应用API函数另外,我还要介绍在一个调试器,他在USER模式下使用有很好的效果,他利用API函数跟踪<BR><BR>PE文件,并把自身进程依附在一个活跃的进程中。在WINDOWS内核的库中,微软提供了这些API函数,<BR><BR>为了跟踪特定的进程,你要使用调试工具。一些重要的API函数包括 CreateThread(), CreateProcess(), <BR><BR>OpenProcess(), DebugActiveProcess(), <BR><BR>GetThreadContext(), SetThreadContext(), ContinueDebugEvent(), DebugBreak(), ReadProcessMemory(), <BR><BR>WriteProcessMemory(), SuspendThread(), and ResumeThread().<BR><BR><BR><B>3.1.2调试器的那些部分是重要的</B> (偶省掉了一些没用的部分)<BR><BR>前面我介绍了两个调试器,但是我并没有说明怎样使用他们。我建议你去看他们的HELP文档,但我还是<BR><BR>想简要的说明一些重要的部分。<BR><BR>1。Registers viewer. <BR><BR>Code: </P>
<P>
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>EAX <BR>ECX <BR>EDX <BR>EBX <BR>ESP <BR>EBP <BR>ESI <BR>EDI <BR>EIP <BR>o d t s z a p c<BR></FONT></FONT></FONT></CODE></TD></TR></TBODY></TABLE></P>
<P><BR><BR><BR>2。Disassembler or Code viewer<BR><BR>Code: </P>
<P>
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>010119E0 PUSH EBP <BR>010119E1 MOV EBP</FONT></FONT><FONT face=新宋体 color=#007700>,</FONT><FONT face=新宋体><FONT color=#0000bb>ESP <BR>010119E3 PUSH </FONT><FONT color=#007700>-</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>1 <BR>010119E5 PUSH 01001570 <BR>010119EA PUSH 01011D60 <BR>010119EF MOV EAX</FONT><FONT color=#007700>,</FONT><FONT color=#0000bb>DWORD PTR FS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>0</FONT></FONT><FONT face=新宋体 color=#007700>] <BR></FONT><FONT face=新宋体><FONT color=#0000bb>010119F5 PUSH EAX <BR>010119F6 MOV DWORD PTR FS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>0</FONT><FONT color=#007700>],</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>ESP <BR>010119FD ADD ESP</FONT><FONT color=#007700>,-</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>68 <BR>01011A00 PUSH EBX <BR>01011A01 PUSH ESI <BR>01011A02 PUSH EDI <BR>01011A03 MOV DWORD PTR SS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>EBP</FONT><FONT color=#007700>-</FONT><FONT color=#0000bb>18</FONT><FONT color=#007700>],</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>ESP <BR>01011A06 MOV DWORD PTR SS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>EBP</FONT><FONT color=#007700>-</FONT><FONT color=#0000bb>4</FONT><FONT color=#007700>],</FONT></FONT><FONT face=新宋体 color=#0000bb>0<BR></FONT></FONT></CODE></TD></TR></TBODY></TABLE></P>
<P><BR><BR><B>3.Memory watcher.</B> <BR><BR>Code: </P>
<P>
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>0023</FONT></FONT><FONT face=新宋体><FONT color=#007700>:</FONT><FONT color=#0000bb>01013000 00 00 00 00 00 00 00 00</FONT><FONT color=#007700>-</FONT><FONT color=#0000bb>00 00 00 00 00 00 00 00 </FONT></FONT><FONT face=新宋体><FONT color=#007700>................ <BR></FONT><FONT color=#0000bb>0023</FONT><FONT color=#007700>:</FONT><FONT color=#0000bb>01013010 01 00 00 00 20 00 00 00</FONT><FONT color=#007700>-</FONT><FONT color=#0000bb>0A 00 00 00 0A 00 00 00 </FONT></FONT><FONT face=新宋体><FONT color=#007700>................ <BR></FONT><FONT color=#0000bb>0023</FONT><FONT color=#007700>:</FONT><FONT color=#0000bb>01013020 20 00 00 00 00 00 00 00</FONT><FONT color=#007700>-</FONT><FONT color=#0000bb>53 63 69 43 61 6C 63 00 </FONT><FONT color=#007700>........</FONT><FONT color=#0000bb>SciCalc</FONT></FONT><FONT face=新宋体><FONT color=#007700>. <BR></FONT><FONT color=#0000bb>0023</FONT><FONT color=#007700>:</FONT><FONT color=#0000bb>01013030 00 00 00 00 00 00 00 00</FONT><FONT color=#007700>-</FONT><FONT color=#0000bb>62 61 63 6B 67 72 6F 75 </FONT><FONT color=#007700>........</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>backgrou <BR>0023</FONT><FONT color=#007700>:</FONT><FONT color=#0000bb>01013040 6E 64 00 00 00 00 00 00</FONT><FONT color=#007700>-</FONT><FONT color=#0000bb>2E 00 00 00 00 00 00 00 nd</FONT></FONT><FONT face=新宋体 color=#007700>..............<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE></P>
<P><BR><FONT size=2>4</FONT> <BR><BR><B>4.Stack viewer. </B><BR><BR>Code: </P>
<P>
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>0010</FONT></FONT><FONT face=新宋体><FONT color=#007700>:</FONT><FONT color=#0000bb>0007FFC4 4F 6D 81 7C 38 07 91 7C</FONT><FONT color=#007700>-</FONT><FONT color=#0000bb>FF FF FF FF 00 90 FD 7F Om </FONT><FONT color=#007700>|</FONT><FONT color=#0000bb>8 ‘</FONT></FONT><FONT face=新宋体><FONT color=#007700>| . <BR></FONT><FONT color=#0000bb>0010</FONT><FONT color=#007700>:</FONT><FONT color=#0000bb>0007FFD4 ED A6 54 80 C8 FF 07 00</FONT><FONT color=#007700>-</FONT><FONT color=#0000bb>E8 B4 F5 81 FF FF FF FF T </FONT></FONT><FONT face=新宋体><FONT color=#007700>. <BR></FONT><FONT color=#0000bb>0010</FONT><FONT color=#007700>:</FONT><FONT color=#0000bb>0007FFE4 F3 99 83 7C 58 6D 81 7C</FONT><FONT color=#007700>-</FONT><FONT color=#0000bb>00 00 00 00 00 00 00 00 Xm </FONT></FONT><FONT face=新宋体><FONT color=#007700>|........ <BR></FONT><FONT color=#0000bb>0010</FONT><FONT color=#007700>:</FONT><FONT color=#0000bb>0007FFF4 00 00 00 00 E0 19 01 01</FONT><FONT color=#007700>-</FONT><FONT color=#0000bb>00 00 00 00 00 00 00 00 </FONT></FONT><FONT face=新宋体 color=#007700>.... ....<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE></P>
<P><BR><BR><B>5.Command line, command buttons, or shortcut keys to follow the debugging process.</B> <BR>Code: </P>
<P>
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>Command SoftICE OllyDbg <BR>Run F5 F9 <BR>Step Into F11 F7 <BR>Step Over F10 F8 <BR>Set </FONT></FONT><FONT face=新宋体 color=#007700>Break </FONT><FONT face=新宋体 color=#0000bb>Point F8 F2<BR></FONT></FONT></CODE></TD></TR></TBODY></TABLE></P>
<P><BR><BR><B>3.2一些有用的工具</B> <BR><BR>一个好的PE开发者要熟悉一些工具来节省他们的时间,所以我替大家选择了一些有用的工具,来分<BR><BR>析可执行文件。<BR><BR><B>3.2.1 LordPE</B> <BR><BR>LordPE仍然是获得PE文件信息并修改他们的首选工具。<BR><BR><IMG alt="" src="http://images.blogcn.com/2006/3/4/2/goblinbest,2006030434628.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0> <BR><BR><B>3.3.2 PEiD</B> <BR><BR>PEiD对于分析编译器,壳种类,入口点来说是一款很好的工具。到现在为止,他能侦测500种以上的PE文<BR><BR>件类型。<BR><BR><IMG alt="" src="http://images.blogcn.com/2006/3/4/2/goblinbest,2006030434855.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0></P>
<P><FONT face="verdana, tahoma, helvetica" size=2>3.3.3 Resource Hacker <BR><BR>他能用来修改一些资源数据信息,如图标,菜单,版本等等。<BR><BR><IMG alt="" src="http://www.codeproject.com/system/inject2exe/resourcehacker.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0><BR><BR>3.3.4 WinHex <BR><BR><IMG alt="" src="http://www.codeproject.com/system/inject2exe/resourcehacker.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0> <BR><BR>3.3.5 CFF Explorer <BR><BR>他支持PE32/64,PE重建包括CIL文件,换句话说就是.NET文件。他使用更方便,功能更强大。<BR><BR><IMG alt="" src="http://www.codeproject.com/system/inject2exe/cffexplorer.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0> <BR><BR>4添加新的节区并改变EPO <BR><BR><BR>我们已经完成了工作的第一步。所以我添加了一个新的节区,并重建了PE文件。在开始前我想让你借助<BR><BR>OD熟悉PE头。用OD载入文件,选择View->Executable file,Special->PE header,你将看到类似图3的画面。<BR><BR>现在在主菜单选择View->Memory,试着在内存映射窗口区别各个节区。<BR><BR><IMG alt="" src="http://images.blogcn.com/2006/3/4/3/goblinbest,20060304459.png" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0><BR><BR><IMG alt="" src="http://images.blogcn.com/2006/3/4/3/goblinbest,2006030441119.png" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0><BR><BR>我想向你解释,我们怎样改变举例文件中的入口点偏移量(CALC.EXE)。首先,使用PE工具,找到入口<BR><BR>点 0x00012475,并且映像基地址为 0x01000000,这个OEP是虚拟地址的相对地址,所以映像基地址来转<BR><BR>变把他为虚拟地址。<BR><BR>Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>Virtual_Address </FONT></FONT><FONT face=新宋体><FONT color=#007700>= </FONT><FONT color=#0000bb>Image_Base </FONT><FONT color=#007700>+ </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>Relative_Virtual_Address <BR><BR>DWORD OEP_RVA </FONT><FONT color=#007700>= </FONT><FONT color=#0000bb>image_nt_headers</FONT><FONT color=#007700>-></FONT><FONT color=#0000bb>OptionalHeader</FONT><FONT color=#007700>.</FONT><FONT color=#0000bb>AddressOfEntryPoint </FONT></FONT><FONT face=新宋体 color=#007700>; <BR></FONT><FONT face=新宋体><FONT color=#ff8000>// OEP_RVA = 0x00012475 <BR></FONT><FONT color=#0000bb>DWORD OEP_VA </FONT><FONT color=#007700>= </FONT><FONT color=#0000bb>image_nt_headers</FONT><FONT color=#007700>-></FONT><FONT color=#0000bb>OptionalHeader</FONT><FONT color=#007700>.</FONT><FONT color=#0000bb>ImageBase </FONT><FONT color=#007700>+ </FONT><FONT color=#0000bb>OEP_RVA </FONT></FONT><FONT face=新宋体 color=#007700>; <BR></FONT><FONT face=新宋体 color=#ff8000>// OEP_VA = 0x01000000 + 0x00012475 = 0x01012475<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR><B>PE Maker - 1</B> <BR><BR><A href="http://www.codeproject.com/system/inject2exe/test1.zip" target=_blank>Download test PE file - 49.5 Kb </A><BR><BR>in loader.cpp文件中的DynLoader()函数用来保存新的节的数据<BR><BR>Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>__stdcall void DynLoader</FONT></FONT><FONT face=新宋体 color=#007700>() <BR>{ <BR></FONT><FONT face=新宋体 color=#0000bb>_asm <BR></FONT><FONT face=新宋体 color=#007700>{ <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//---------------------------------- <BR></FONT><FONT color=#0000bb>DWORD_TYPE</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>DYN_LOADER_START_MAGIC</FONT></FONT><FONT face=新宋体 color=#007700>) <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//---------------------------------- <BR></FONT><FONT color=#0000bb>MOV EAX</FONT><FONT color=#007700>,</FONT><FONT color=#0000bb>01012475h </FONT></FONT><FONT face=新宋体 color=#ff8000>// << Original OEP <BR></FONT><FONT face=新宋体 color=#0000bb>JMP EAX <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//---------------------------------- <BR></FONT><FONT color=#0000bb>DWORD_TYPE</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>DYN_LOADER_END_MAGIC</FONT></FONT><FONT face=新宋体 color=#007700>) <BR></FONT><FONT face=新宋体 color=#ff8000>//---------------------------------- <BR></FONT><FONT face=新宋体 color=#007700>} <BR>}<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>不幸的是这个源代码只能在sample test file. 中应用,我们应该借助于在新的节区保存前面的OEP的值,来<BR><BR>完善他,并使用他到达真正的OEP。我会在在 Step 2 完善他<BR><BR>4.1找回并重建PE文件<BR><BR>为了使用新的PE文件,我写了一个简单的类库文件,来修复PE信息。<BR><BR>Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>CPELibrary </FONT></FONT><FONT face=新宋体 color=#007700>Class </FONT><FONT face=新宋体 color=#0000bb>Step 1 <BR></FONT><FONT face=新宋体 color=#007700>---------------------------------------------------------------- <BR>class </FONT><FONT face=新宋体 color=#0000bb>CPELibrary <BR></FONT><FONT face=新宋体><FONT color=#007700>{ <BR></FONT><FONT color=#0000bb>private</FONT></FONT><FONT face=新宋体 color=#007700>: <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//----------------------------------------- <BR></FONT><FONT color=#0000bb>PCHARpMem</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDdwFileSize</FONT></FONT><FONT face=新宋体 color=#007700>; <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//----------------------------------------- <BR></FONT><FONT color=#0000bb>protected</FONT></FONT><FONT face=新宋体 color=#007700>: <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//----------------------------------------- <BR></FONT><FONT color=#0000bb>PIMAGE_DOS_HEADERimage_dos_header</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>PCHARpDosStub</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDdwDosStubSize</FONT><FONT color=#007700>, </FONT><FONT color=#0000bb>dwDosStubOffset</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>PIMAGE_NT_HEADERSimage_nt_headers</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>PIMAGE_SECTION_HEADERimage_section_header</FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>MAX_SECTION_NUM</FONT></FONT><FONT face=新宋体><FONT color=#007700>]; <BR></FONT><FONT color=#0000bb>PCHARimage_section</FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>MAX_SECTION_NUM</FONT></FONT><FONT face=新宋体 color=#007700>]; <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//----------------------------------------- <BR></FONT><FONT color=#0000bb>protected</FONT></FONT><FONT face=新宋体 color=#007700>: <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//----------------------------------------- <BR></FONT><FONT color=#0000bb>DWORD PEAlign</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>DWORD dwTarNum</FONT><FONT color=#007700>,</FONT><FONT color=#0000bb>DWORD dwAlignTo</FONT></FONT><FONT face=新宋体><FONT color=#007700>); <BR></FONT><FONT color=#0000bb>void AlignmentSections</FONT></FONT><FONT face=新宋体 color=#007700>(); <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//----------------------------------------- <BR></FONT><FONT color=#0000bb>DWORD Offset2RVA</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>DWORD dwRO</FONT></FONT><FONT face=新宋体><FONT color=#007700>); <BR></FONT><FONT color=#0000bb>DWORD RVA2Offset</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>DWORD dwRVA</FONT></FONT><FONT face=新宋体 color=#007700>); <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//----------------------------------------- <BR></FONT><FONT color=#0000bb>PIMAGE_SECTION_HEADER ImageRVA2Section</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>DWORD dwRVA</FONT></FONT><FONT face=新宋体><FONT color=#007700>); <BR></FONT><FONT color=#0000bb>PIMAGE_SECTION_HEADER ImageOffset2Section</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>DWORD dwRO</FONT></FONT><FONT face=新宋体 color=#007700>); <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//----------------------------------------- <BR></FONT><FONT color=#0000bb>DWORD ImageOffset2SectionNum</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>DWORD dwRVA</FONT></FONT><FONT face=新宋体><FONT color=#007700>); <BR></FONT><FONT color=#0000bb>PIMAGE_SECTION_HEADER AddNewSection</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>char</FONT><FONT color=#007700>* </FONT><FONT color=#0000bb>szName</FONT><FONT color=#007700>,</FONT><FONT color=#0000bb>DWORD dwSize</FONT></FONT><FONT face=新宋体 color=#007700>); <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//----------------------------------------- <BR></FONT><FONT color=#0000bb>public</FONT></FONT><FONT face=新宋体 color=#007700>: <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//----------------------------------------- <BR></FONT><FONT color=#0000bb>CPELibrary</FONT></FONT><FONT face=新宋体><FONT color=#007700>(); <BR>~</FONT><FONT color=#0000bb>CPELibrary</FONT></FONT><FONT face=新宋体 color=#007700>(); <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//----------------------------------------- <BR></FONT><FONT color=#0000bb>void OpenFile</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>char</FONT><FONT color=#007700>* </FONT><FONT color=#0000bb>FileName</FONT></FONT><FONT face=新宋体><FONT color=#007700>); <BR></FONT><FONT color=#0000bb>void SaveFile</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>char</FONT><FONT color=#007700>* </FONT><FONT color=#0000bb>FileName</FONT></FONT><FONT face=新宋体 color=#007700>); <BR></FONT><FONT face=新宋体 color=#ff8000>//----------------------------------------- <BR></FONT><FONT face=新宋体 color=#007700>};<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR><BR>借助于表1,image_dos_header, pDosStub, image_nt_headers, image_section_header [MAX_SECTION_NUM], 和<BR><BR>image_section[MAX_SECTION_NUM] 的用法是很清晰的。我们使用OpenFile()和SaveFile()来重新得到并重建<BR><BR>PE文件此外,一个重要的阶段是使用AddNewSection()来创造新的节区。<BR><BR>4.2为新的节区添加数据<BR><BR>在pecrypt.cpp中,我构建了另一个类,CPECryptor来包含新节区的数据。新节区的数据由loader.cpp文件中<BR><BR>的DynLoader()函数构建。DynLoader Step 1.我们也使用CPECryptor类来填充其他资料。<BR>Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>CPECryptor </FONT></FONT><FONT face=新宋体 color=#007700>Class </FONT><FONT face=新宋体 color=#0000bb>Step 1 <BR></FONT><FONT face=新宋体><FONT color=#007700>---------------------------------------------------------------- <BR>class </FONT><FONT color=#0000bb>CPECryptor</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体 color=#0000bb>public CPELibrary <BR></FONT><FONT face=新宋体><FONT color=#007700>{ <BR></FONT><FONT color=#0000bb>private</FONT></FONT><FONT face=新宋体 color=#007700>: <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//---------------------------------------- <BR></FONT><FONT color=#0000bb>PCHAR pNewSection</FONT></FONT><FONT face=新宋体 color=#007700>; <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//---------------------------------------- <BR></FONT><FONT color=#0000bb>DWORD GetFunctionVA</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>void</FONT><FONT color=#007700>* </FONT><FONT color=#0000bb>FuncName</FONT></FONT><FONT face=新宋体><FONT color=#007700>); <BR></FONT><FONT color=#0000bb>void</FONT><FONT color=#007700>* </FONT><FONT color=#0000bb>ReturnToBytePtr</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>void</FONT><FONT color=#007700>* </FONT><FONT color=#0000bb>FuncName</FONT><FONT color=#007700>, </FONT><FONT color=#0000bb>DWORD findstr</FONT></FONT><FONT face=新宋体 color=#007700>); <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//---------------------------------------- <BR></FONT><FONT color=#0000bb>protected</FONT></FONT><FONT face=新宋体 color=#007700>: <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//---------------------------------------- <BR></FONT><FONT color=#0000bb>public</FONT></FONT><FONT face=新宋体 color=#007700>: <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//---------------------------------------- <BR></FONT><FONT color=#0000bb>void CryptFile</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>int</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>__cdecl </FONT><FONT color=#007700>*</FONT><FONT color=#0000bb>callback</FONT><FONT color=#007700>) (</FONT><FONT color=#0000bb>unsigned int</FONT><FONT color=#007700>, </FONT><FONT color=#0000bb>unsigned int</FONT></FONT><FONT face=新宋体 color=#007700>)); <BR></FONT><FONT face=新宋体 color=#ff8000>//---------------------------------------- <BR></FONT><FONT face=新宋体 color=#007700>}; <BR></FONT><FONT color=#ff8000><FONT face=新宋体>//----------------------------------------------------------------</FONT><BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR></FONT></P>
<P><BR></P></STRONG></CODE> 4.3一些关于构建新的PE文件的说明<BR><BR>用一下片断来排列虚拟地址和每个节区的虚拟大小<BR><BR>Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>image_section_header</FONT></FONT><FONT face=新宋体><FONT color=#007700>[</FONT><FONT color=#0000bb>i</FONT><FONT color=#007700>]-></FONT><FONT color=#0000bb>VirtualAddress</FONT></FONT><FONT face=新宋体><FONT color=#007700>= <BR></FONT><FONT color=#0000bb>PEAlign</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>image_section_header</FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>i</FONT><FONT color=#007700>]-></FONT><FONT color=#0000bb>VirtualAddress</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#0000bb>image_nt_headers</FONT><FONT color=#007700>-></FONT><FONT color=#0000bb>OptionalHeader</FONT><FONT color=#007700>.</FONT><FONT color=#0000bb>SectionAlignment</FONT></FONT><FONT face=新宋体><FONT color=#007700>); <BR><BR></FONT><FONT color=#0000bb>image_section_header</FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>i</FONT><FONT color=#007700>]-></FONT><FONT color=#0000bb>Misc</FONT><FONT color=#007700>.</FONT><FONT color=#0000bb>VirtualSize</FONT></FONT><FONT face=新宋体><FONT color=#007700>= <BR></FONT><FONT color=#0000bb>PEAlign</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>image_section_header</FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>i</FONT><FONT color=#007700>]-></FONT><FONT color=#0000bb>Misc</FONT><FONT color=#007700>.</FONT><FONT color=#0000bb>VirtualSize</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#0000bb>image_nt_headers</FONT><FONT color=#007700>-></FONT><FONT color=#0000bb>OptionalHeader</FONT><FONT color=#007700>.</FONT><FONT color=#0000bb>SectionAlignment</FONT></FONT><FONT face=新宋体 color=#007700>);<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>Align the PointerToRawData and the SizeOfRawData of each section by FileAlignment<BR><BR>Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>image_section_header</FONT></FONT><FONT face=新宋体><FONT color=#007700>[</FONT><FONT color=#0000bb>i</FONT><FONT color=#007700>]-></FONT><FONT color=#0000bb>PointerToRawData </FONT></FONT><FONT face=新宋体><FONT color=#007700>= <BR></FONT><FONT color=#0000bb>PEAlign</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>image_section_header</FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>i</FONT><FONT color=#007700>]-></FONT><FONT color=#0000bb>PointerToRawData</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#0000bb>image_nt_headers</FONT><FONT color=#007700>-></FONT><FONT color=#0000bb>OptionalHeader</FONT><FONT color=#007700>.</FONT><FONT color=#0000bb>FileAlignment</FONT></FONT><FONT face=新宋体><FONT color=#007700>); <BR><BR></FONT><FONT color=#0000bb>image_section_header</FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>i</FONT><FONT color=#007700>]-></FONT><FONT color=#0000bb>SizeOfRawData </FONT></FONT><FONT face=新宋体><FONT color=#007700>= <BR></FONT><FONT color=#0000bb>PEAlign</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>image_section_header</FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>i</FONT><FONT color=#007700>]-></FONT><FONT color=#0000bb>SizeOfRawData</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#0000bb>image_nt_headers</FONT><FONT color=#007700>-></FONT><FONT color=#0000bb>OptionalHeader</FONT><FONT color=#007700>.</FONT><FONT color=#0000bb>FileAlignment</FONT></FONT><FONT face=新宋体 color=#007700>);<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>Correct the SizeofImage by the virtual size and the virtual address of the last section<BR><BR>Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>image_nt_headers</FONT></FONT><FONT face=新宋体><FONT color=#007700>-></FONT><FONT color=#0000bb>OptionalHeader</FONT><FONT color=#007700>.</FONT><FONT color=#0000bb>SizeOfImage </FONT></FONT><FONT face=新宋体><FONT color=#007700>= <BR></FONT><FONT color=#0000bb>image_section_header</FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>LastSection</FONT><FONT color=#007700>]-></FONT><FONT color=#0000bb>VirtualAddress </FONT></FONT><FONT face=新宋体><FONT color=#007700>+ <BR></FONT><FONT color=#0000bb>image_section_header</FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>LastSection</FONT><FONT color=#007700>]-></FONT><FONT color=#0000bb>Misc</FONT><FONT color=#007700>.</FONT><FONT color=#0000bb>VirtualSize</FONT></FONT><FONT face=新宋体 color=#007700>;<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>Set the Bound Import Directory header to zero, as this directory is not very important to execute a PE file: <BR><BR>Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>image_nt_headers</FONT></FONT><FONT face=新宋体><FONT color=#007700>-> <BR></FONT><FONT color=#0000bb>OptionalHeader</FONT><FONT color=#007700>.</FONT><FONT color=#0000bb>DataDirectory</FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT</FONT></FONT><FONT face=新宋体><FONT color=#007700>]. <BR></FONT><FONT color=#0000bb>VirtualAddress </FONT><FONT color=#007700>= </FONT><FONT color=#0000bb>0</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>image_nt_headers</FONT></FONT><FONT face=新宋体><FONT color=#007700>-> <BR></FONT><FONT color=#0000bb>OptionalHeader</FONT><FONT color=#007700>.</FONT><FONT color=#0000bb>DataDirectory</FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT</FONT><FONT color=#007700>].</FONT><FONT color=#0000bb>Size </FONT><FONT color=#007700>= </FONT><FONT color=#0000bb>0</FONT></FONT><FONT face=新宋体 color=#007700>;<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>4.4一些关于连接这个VC程序的解释<BR><BR>Set Linker->General->Enable Incremental Linking to No (/INCREMENTAL:NO). <BR><BR><IMG alt="" src="http://www.codeproject.com/system/inject2exe/linktip1.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0> <BR><BR>你能了解增加连接和不增加连接之间的不同<BR><BR><IMG alt="" src="http://www.codeproject.com/system/inject2exe/incremental_link.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0> <BR><BR>为了获得DynLoader(), 的虚拟地址,再增加LINK中我们获得JMP pemaker.DynLoader 的虚拟地址。但是不使<BR><BR>用LINK时用以下代码获得地址<BR><BR>Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>DWORD dwVA</FONT></FONT><FONT face=新宋体><FONT color=#007700>= (</FONT><FONT color=#0000bb>DWORD</FONT><FONT color=#007700>) </FONT><FONT color=#0000bb>DynLoader</FONT></FONT><FONT face=新宋体 color=#007700>;<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>This setting is more critical in the incremental link when you try to find the beginning and ending of the Loader, <BR><BR>DynLoader(), by CPECryptor::ReturnToBytePtr():(抱歉,这句话偶不知道如何才能翻译通顺 <IMG alt="" src="http://www.ph4nt0m.org/bbs/images/smilies/confused.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0> )<BR><BR>Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>void</FONT></FONT><FONT face=新宋体><FONT color=#007700>* </FONT><FONT color=#0000bb>CPECryptor</FONT><FONT color=#007700>::</FONT><FONT color=#0000bb>ReturnToBytePtr</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>void</FONT><FONT color=#007700>* </FONT><FONT color=#0000bb>FuncName</FONT><FONT color=#007700>, </FONT><FONT color=#0000bb>DWORD findstr</FONT></FONT><FONT face=新宋体><FONT color=#007700>) <BR>{ <BR></FONT><FONT color=#0000bb>void</FONT><FONT color=#007700>* </FONT><FONT color=#0000bb>tmpd</FONT></FONT><FONT face=新宋体 color=#007700>; <BR></FONT><FONT face=新宋体 color=#0000bb>__asm <BR></FONT><FONT face=新宋体><FONT color=#007700>{ <BR></FONT><FONT color=#0000bb>mov eax</FONT><FONT color=#007700>, </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>FuncName <BR>jmp df <BR>hjg</FONT><FONT color=#007700>:</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>inc eax <BR>df</FONT><FONT color=#007700>:</FONT><FONT color=#0000bb>mov ebx</FONT><FONT color=#007700>, [</FONT><FONT color=#0000bb>eax</FONT></FONT><FONT face=新宋体><FONT color=#007700>] <BR></FONT><FONT color=#0000bb>cmp ebx</FONT><FONT color=#007700>, </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>findstr <BR>jnz hjg <BR>mov tmpd</FONT><FONT color=#007700>, </FONT></FONT><FONT face=新宋体 color=#0000bb>eax <BR></FONT><FONT face=新宋体><FONT color=#007700>} <BR>return </FONT><FONT color=#0000bb>tmpd</FONT></FONT><FONT face=新宋体 color=#007700>; <BR>}<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>5.保存重要的数据和延伸原入口点<BR><BR>现在,我们已经保存了原入口点,并映射了基地址以便于到达虚拟地址入口点。在DynLoader()结尾处我已<BR><BR>经保存一个空白区来储存这些重要的数据。DynLoader Step 2.<BR><BR><B>PE Maker - Step 2</B> <BR><BR><A href="http://www.codeproject.com/system/inject2exe/pemaker2.zip" target=_blank>Download source files - 58.3 Kb </A><BR><BR>Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>DynLoaderStep2</FONT></FONT><FONT face=新宋体 color=#007700>></FONT><FONT face=新宋体 color=#0000bb>DynLoader Step 2 <BR><BR>__stdcall void DynLoader</FONT><FONT face=新宋体 color=#007700>() <BR>{ <BR></FONT><FONT face=新宋体 color=#0000bb>_asm <BR></FONT><FONT face=新宋体 color=#007700>{ <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//---------------------------------- <BR></FONT><FONT color=#0000bb>DWORD_TYPE</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>DYN_LOADER_START_MAGIC</FONT></FONT><FONT face=新宋体 color=#007700>) <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//---------------------------------- <BR></FONT><FONT color=#0000bb>Main_0</FONT></FONT><FONT face=新宋体 color=#007700>: <BR></FONT><FONT face=新宋体 color=#0000bb>PUSHAD <BR></FONT><FONT face=新宋体 color=#ff8000>// get base ebp <BR></FONT><FONT face=新宋体 color=#0000bb>CALL Main_1 <BR>Main_1</FONT><FONT face=新宋体 color=#007700>: <BR></FONT><FONT face=新宋体><FONT color=#0000bb>POP EBP <BR>SUB EBP</FONT><FONT color=#007700>,</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>OFFSET Main_1 <BR>MOV EAX</FONT><FONT color=#007700>,</FONT><FONT color=#0000bb>DWORD PTR </FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>EBP</FONT><FONT color=#007700>+</FONT><FONT color=#0000bb>_RO_dwImageBase</FONT></FONT><FONT face=新宋体><FONT color=#007700>] <BR></FONT><FONT color=#0000bb>ADD EAX</FONT><FONT color=#007700>,</FONT><FONT color=#0000bb>DWORD PTR </FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>EBP</FONT><FONT color=#007700>+</FONT><FONT color=#0000bb>_RO_dwOrgEntryPoint</FONT></FONT><FONT face=新宋体 color=#007700>] <BR></FONT><FONT face=新宋体 color=#0000bb>PUSH EAX <BR>RETN </FONT><FONT face=新宋体><FONT color=#ff8000>// >> JMP to Original OEP <BR>//---------------------------------- <BR></FONT><FONT color=#0000bb>DWORD_TYPE</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>DYN_LOADER_START_DATA1</FONT></FONT><FONT face=新宋体 color=#007700>) <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//----------------------------------<FONT color=red> <BR></FONT><FONT color=#0000bb>_RO_dwImageBase</FONT><FONT color=#007700>:</FONT><FONT color=#0000bb>DWORD_TYPE</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>0xCCCCCCCC</FONT></FONT><FONT face=新宋体><FONT color=#007700>) <BR></FONT><FONT color=#0000bb>_RO_dwOrgEntryPoint</FONT><FONT color=#007700>:</FONT><FONT color=#0000bb>DWORD_TYPE</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>0xCCCCCCCC</FONT><FONT color=#007700>)</</FONT><FONT color=#0000bb>FONT</FONT></FONT><FONT face=新宋体 color=#007700>> <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//---------------------------------- <BR></FONT><FONT color=#0000bb>DWORD_TYPE</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>DYN_LOADER_END_MAGIC</FONT></FONT><FONT face=新宋体 color=#007700>) <BR></FONT><FONT face=新宋体 color=#ff8000>//---------------------------------- <BR></FONT><FONT face=新宋体 color=#007700>} <BR>}<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>5.1恢复开始时寄存器间的关系<BR><BR>恢复他们间的关系是重要的,但在DynLoader Step 2的源代码中我们还没有做这件事。我们可以修改<BR><BR>DynLoader() 函数来重建开始的关系<BR><BR>Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>__stdcall void DynLoader</FONT></FONT><FONT face=新宋体 color=#007700>() <BR>{ <BR></FONT><FONT face=新宋体 color=#0000bb>_asm <BR></FONT><FONT face=新宋体 color=#007700>{ <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//---------------------------------- <BR></FONT><FONT color=#0000bb>DWORD_TYPE</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>DYN_LOADER_START_MAGIC</FONT></FONT><FONT face=新宋体 color=#007700>) <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//---------------------------------- <BR></FONT><FONT color=#0000bb>Main_0</FONT></FONT><FONT face=新宋体><FONT color=#007700>: <BR><</FONT><FONT color=#0000bb>FONT color</FONT><FONT color=#007700>=</FONT><FONT color=#0000bb>red</FONT><FONT color=#007700>></FONT><FONT color=#0000bb>PUSHAD</FONT></FONT><FONT face=新宋体 color=#ff8000>// Save the registers context in stack</FONT> <BR></FONT><FONT face=新宋体 color=#0000bb>CALL Main_1 <BR>Main_1</FONT><FONT face=新宋体><FONT color=#007700>: <BR></FONT><FONT color=#0000bb>POP EBP</FONT></FONT><FONT face=新宋体><FONT color=#ff8000>// Get Base EBP <BR></FONT><FONT color=#0000bb>SUB EBP</FONT><FONT color=#007700>,</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>OFFSET Main_1 <BR>MOV EAX</FONT><FONT color=#007700>,</FONT><FONT color=#0000bb>DWORD PTR </FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>EBP</FONT><FONT color=#007700>+</FONT><FONT color=#0000bb>_RO_dwImageBase</FONT></FONT><FONT face=新宋体><FONT color=#007700>] <BR></FONT><FONT color=#0000bb>ADD EAX</FONT><FONT color=#007700>,</FONT><FONT color=#0000bb>DWORD PTR </FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>EBP</FONT><FONT color=#007700>+</FONT><FONT color=#0000bb>_RO_dwOrgEntryPoint</FONT></FONT><FONT face=新宋体><FONT color=#007700>] <BR></FONT><FONT color=#0000bb>MOV DWORD PTR </FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>ESP</FONT><FONT color=#007700>+</FONT><FONT color=#0000bb>1Ch</FONT><FONT color=#007700>],</FONT><FONT color=#0000bb>EAX </FONT></FONT><FONT face=新宋体><FONT color=#ff8000>// pStack.Eax <- EAX <BR></FONT><FONT color=#007700><</FONT><FONT color=#0000bb>FONT color</FONT><FONT color=#007700>=</FONT><FONT color=#0000bb>red</FONT><FONT color=#007700>></FONT><FONT color=#0000bb>POPAD </FONT></FONT><FONT face=新宋体 color=#ff8000>// Restore the first registers context from stack</FONT> <BR></FONT><FONT face=新宋体><FONT color=#0000bb>PUSH EAX <BR></FONT><FONT color=#007700>XOR</FONT><FONT color=#0000bb>EAX</FONT><FONT color=#007700>, </FONT></FONT><FONT face=新宋体 color=#0000bb>EAX <BR>RETN </FONT><FONT face=新宋体><FONT color=#ff8000>// >> JMP to Original OEP <BR>//---------------------------------- <BR></FONT><FONT color=#0000bb>DWORD_TYPE</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>DYN_LOADER_START_DATA1</FONT></FONT><FONT face=新宋体 color=#007700>) <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//---------------------------------- <BR></FONT><FONT color=#0000bb>_RO_dwImageBase</FONT><FONT color=#007700>:</FONT><FONT color=#0000bb>DWORD_TYPE</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>0xCCCCCCCC</FONT></FONT><FONT face=新宋体><FONT color=#007700>) <BR></FONT><FONT color=#0000bb>_RO_dwOrgEntryPoint</FONT><FONT color=#007700>:</FONT><FONT color=#0000bb>DWORD_TYPE</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>0xCCCCCCCC</FONT></FONT><FONT face=新宋体 color=#007700>) <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//---------------------------------- <BR></FONT><FONT color=#0000bb>DWORD_TYPE</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>DYN_LOADER_END_MAGIC</FONT></FONT><FONT face=新宋体 color=#007700>) <BR></FONT><FONT face=新宋体 color=#ff8000>//---------------------------------- <BR></FONT><FONT face=新宋体 color=#007700>} <BR>}<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>5.2恢复最初的堆栈<BR><BR>我们能利用设置在堆栈开始处的值加0x34到原入口点,来恢复原始的堆栈,但这不是很重要。然而在下<BR><BR>面的代码中我用了一个简单的技巧来到达OEP以便于修改堆栈,你能利用OD来跟踪执行过程。<BR><BR>Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>__stdcall void DynLoader</FONT></FONT><FONT face=新宋体 color=#007700>() <BR>{ <BR></FONT><FONT face=新宋体 color=#0000bb>_asm <BR></FONT><FONT face=新宋体 color=#007700>{ <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//---------------------------------- <BR></FONT><FONT color=#0000bb>DWORD_TYPE</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>DYN_LOADER_START_MAGIC</FONT></FONT><FONT face=新宋体 color=#007700>) <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//---------------------------------- <BR></FONT><FONT color=#0000bb>Main_0</FONT></FONT><FONT face=新宋体><FONT color=#007700>: <BR></FONT><FONT color=#0000bb>PUSHAD </FONT></FONT><FONT face=新宋体 color=#ff8000>// Save the registers context in stack <BR></FONT><FONT face=新宋体 color=#0000bb>CALL Main_1 <BR>Main_1</FONT><FONT face=新宋体 color=#007700>: <BR></FONT><FONT face=新宋体><FONT color=#0000bb>POP EBP <BR>SUB EBP</FONT><FONT color=#007700>,</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>OFFSET Main_1 <BR>MOV EAX</FONT><FONT color=#007700>,</FONT><FONT color=#0000bb>DWORD PTR </FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>EBP</FONT><FONT color=#007700>+</FONT><FONT color=#0000bb>_RO_dwImageBase</FONT></FONT><FONT face=新宋体><FONT color=#007700>] <BR></FONT><FONT color=#0000bb>ADD EAX</FONT><FONT color=#007700>,</FONT><FONT color=#0000bb>DWORD PTR </FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>EBP</FONT><FONT color=#007700>+</FONT><FONT color=#0000bb>_RO_dwOrgEntryPoint</FONT></FONT><FONT face=新宋体><FONT color=#007700>] <BR></FONT><FONT color=#0000bb>MOV DWORD PTR </FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>ESP</FONT><FONT color=#007700>+</FONT><FONT color=#0000bb>54h</FONT><FONT color=#007700>],</FONT><FONT color=#0000bb>EAX </FONT></FONT><FONT face=新宋体><FONT color=#ff8000>// pStack.Eip <- EAX <BR></FONT><FONT color=#0000bb>POPAD </FONT></FONT><FONT face=新宋体 color=#ff8000>// Restore the first registers context from stack <BR></FONT><FONT face=新宋体><FONT color=#0000bb>CALL _OEP_Jump <BR>DWORD_TYPE</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>0xCCCCCCCC</FONT></FONT><FONT face=新宋体><FONT color=#007700>) <BR></FONT><FONT color=#0000bb>_OEP_Jump</FONT></FONT><FONT face=新宋体 color=#007700>: <BR></FONT><FONT face=新宋体><FONT color=#0000bb>PUSH EBP <BR>MOV EBP</FONT><FONT color=#007700>,</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>ESP <BR>MOV EAX</FONT><FONT color=#007700>,</FONT><FONT color=#0000bb>DWORD PTR </FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>ESP</FONT><FONT color=#007700>+</FONT><FONT color=#0000bb>3Ch</FONT><FONT color=#007700>] </FONT></FONT><FONT face=新宋体><FONT color=#ff8000>// EAX <- pStack.Eip <BR></FONT><FONT color=#0000bb>MOV DWORD PTR </FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>ESP</FONT><FONT color=#007700>+</FONT><FONT color=#0000bb>4h</FONT><FONT color=#007700>],</FONT><FONT color=#0000bb>EAX</FONT></FONT><FONT face=新宋体><FONT color=#ff8000>// _OEP_Jump RETURN pointer <- EAX <BR></FONT><FONT color=#007700>XOR </FONT><FONT color=#0000bb>EAX</FONT><FONT color=#007700>,</FONT></FONT><FONT face=新宋体 color=#0000bb>EAX <BR>LEAVE <BR>RETN <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//---------------------------------- <BR></FONT><FONT color=#0000bb>DWORD_TYPE</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>DYN_LOADER_START_DATA1</FONT></FONT><FONT face=新宋体 color=#007700>) <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//---------------------------------- <BR></FONT><FONT color=#0000bb>_RO_dwImageBase</FONT><FONT color=#007700>:</FONT><FONT color=#0000bb>DWORD_TYPE</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>0xCCCCCCCC</FONT></FONT><FONT face=新宋体><FONT color=#007700>) <BR></FONT><FONT color=#0000bb>_RO_dwOrgEntryPoint</FONT><FONT color=#007700>:</FONT><FONT color=#0000bb>DWORD_TYPE</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>0xCCCCCCCC</FONT></FONT><FONT face=新宋体 color=#007700>) <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//---------------------------------- <BR></FONT><FONT color=#0000bb>DWORD_TYPE</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>DYN_LOADER_END_MAGIC</FONT></FONT><FONT face=新宋体 color=#007700>) <BR></FONT><FONT face=新宋体 color=#ff8000>//---------------------------------- <BR></FONT><FONT face=新宋体 color=#007700>} <BR>}<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>5.3Approach OEP by Structured Exception Handling(借助于构造异常处理来接近OEP)<BR><BR>当程序执行了错误的代码就会抛出一个异常,在这种条件下,程序迅速跳转到一个叫做异常处理的功能<BR><BR>中。<BR><BR>下面的文件包含了异常处理的调用,异常的抛出,以及其功能。<BR><BR>Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR></FONT><FONT face=新宋体><FONT color=#ff8000>#include "stdafx.h" <BR>#include "windows.h" <BR><BR></FONT><FONT color=#0000bb>void RAISE_AN_EXCEPTION</FONT></FONT><FONT face=新宋体 color=#007700>() <BR>{ <BR></FONT><FONT face=新宋体 color=#0000bb>_asm <BR></FONT><FONT face=新宋体 color=#007700>{ <BR></FONT><FONT face=新宋体 color=#0000bb>INT 3 <BR>INT 3 <BR>INT 3 <BR>INT 3 <BR></FONT><FONT face=新宋体><FONT color=#007700>} <BR>} <BR><BR></FONT><FONT color=#0000bb>int _tmain</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>int argc</FONT><FONT color=#007700>, </FONT><FONT color=#0000bb>_TCHAR</FONT><FONT color=#007700>* </FONT><FONT color=#0000bb>argv</FONT></FONT><FONT face=新宋体 color=#007700>[]) <BR>{ <BR></FONT><FONT face=新宋体 color=#0000bb>__try <BR></FONT><FONT face=新宋体><FONT color=#007700>{ <BR></FONT><FONT color=#0000bb>__try</FONT></FONT><FONT face=新宋体><FONT color=#007700>{ <BR></FONT><FONT color=#0000bb>printf</FONT><FONT color=#007700>(</FONT><FONT color=#dd0000>"1: Raise an Exception\n"</FONT></FONT><FONT face=新宋体><FONT color=#007700>); <BR></FONT><FONT color=#0000bb>RAISE_AN_EXCEPTION</FONT></FONT><FONT face=新宋体 color=#007700>(); <BR>} <BR></FONT><FONT face=新宋体 color=#0000bb>__finally <BR></FONT><FONT face=新宋体><FONT color=#007700>{ <BR></FONT><FONT color=#0000bb>printf</FONT><FONT color=#007700>(</FONT><FONT color=#dd0000>"2: In Finally\n"</FONT></FONT><FONT face=新宋体><FONT color=#007700>); <BR>} <BR>} <BR></FONT><FONT color=#0000bb>__except</FONT><FONT color=#007700>( </FONT><FONT color=#0000bb>printf</FONT><FONT color=#007700>(</FONT><FONT color=#dd0000>"3: In Filter\n"</FONT><FONT color=#007700>), </FONT><FONT color=#0000bb>EXCEPTION_EXECUTE_HANDLER </FONT></FONT><FONT face=新宋体><FONT color=#007700>) <BR>{ <BR></FONT><FONT color=#0000bb>printf</FONT><FONT color=#007700>(</FONT><FONT color=#dd0000>"4: In Exception Handler\n"</FONT></FONT><FONT face=新宋体><FONT color=#007700>); <BR>} <BR>return </FONT><FONT color=#0000bb>0</FONT></FONT><FONT face=新宋体 color=#007700>; <BR>}<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>;Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>main</FONT></FONT><FONT face=新宋体><FONT color=#007700>() <BR></FONT><FONT color=#0000bb>00401000</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>PUSH EBP <BR>00401001</FONT><FONT color=#007700>: </FONT><FONT color=#0000bb>MOV EBP</FONT><FONT color=#007700>,</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>ESP <BR>00401003</FONT><FONT color=#007700>: </FONT><FONT color=#0000bb>PUSH </FONT><FONT color=#007700>-</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>1 <BR>00401005</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>PUSH 00407160 <BR></FONT><FONT color=#007700>; </FONT><FONT color=#0000bb>__try </FONT></FONT><FONT face=新宋体><FONT color=#007700>{ <BR>; </FONT><FONT color=#0000bb>the structured exception handler </FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>SEH</FONT><FONT color=#007700>) </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>installation <BR>0040100A</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>PUSH _except_handler3 <BR>0040100F</FONT><FONT color=#007700>: </FONT><FONT color=#0000bb>MOV EAX</FONT><FONT color=#007700>,</FONT><FONT color=#0000bb>DWORD PTR FS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>0</FONT></FONT><FONT face=新宋体><FONT color=#007700>] <BR></FONT><FONT color=#0000bb>00401015</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>PUSH EAX <BR>00401016</FONT><FONT color=#007700>: </FONT><FONT color=#0000bb>MOV DWORD PTR FS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>0</FONT><FONT color=#007700>],</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>ESP <BR>0040101D</FONT><FONT color=#007700>: </FONT><FONT color=#0000bb>SUB ESP</FONT><FONT color=#007700>,</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>8 <BR>00401020</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>PUSH EBX <BR>00401021</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>PUSH ESI <BR>00401022</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>PUSH EDI <BR>00401023</FONT><FONT color=#007700>: </FONT><FONT color=#0000bb>MOV DWORD PTR SS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>EBP</FONT><FONT color=#007700>-</FONT><FONT color=#0000bb>18</FONT><FONT color=#007700>],</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>ESP <BR></FONT><FONT color=#007700>;</FONT><FONT color=#0000bb>__try </FONT></FONT><FONT face=新宋体><FONT color=#007700>{ <BR></FONT><FONT color=#0000bb>00401026</FONT><FONT color=#007700>: XOR </FONT><FONT color=#0000bb>ESI</FONT><FONT color=#007700>,</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>ESI <BR>00401028</FONT><FONT color=#007700>: </FONT><FONT color=#0000bb>MOV DWORD PTR SS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>EBP</FONT><FONT color=#007700>-</FONT><FONT color=#0000bb>4</FONT><FONT color=#007700>],</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>ESI <BR>0040102B</FONT><FONT color=#007700>: </FONT><FONT color=#0000bb>MOV DWORD PTR SS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>EBP</FONT><FONT color=#007700>-</FONT><FONT color=#0000bb>4</FONT><FONT color=#007700>],</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>1 <BR>00401032</FONT><FONT color=#007700>: </FONT><FONT color=#0000bb>PUSH OFFSET </FONT></FONT><FONT face=新宋体><FONT color=#dd0000>"1: Raise an Exception" <BR></FONT><FONT color=#0000bb>00401037</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>CALL printf <BR>0040103C</FONT><FONT color=#007700>: </FONT><FONT color=#0000bb>ADD ESP</FONT><FONT color=#007700>,</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>4 <BR></FONT><FONT color=#007700>; </FONT><FONT color=#0000bb>the raise a exception</FONT><FONT color=#007700>, </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>INT 3 exception <BR></FONT><FONT color=#007700>; </FONT><FONT color=#0000bb>RAISE_AN_EXCEPTION</FONT></FONT><FONT face=新宋体><FONT color=#007700>() <BR></FONT><FONT color=#0000bb>0040103F</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>INT3 <BR>00401040</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>INT3 <BR>00401041</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>INT3 <BR>00401042</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>INT3 <BR></FONT><FONT color=#007700>;} </FONT><FONT color=#0000bb>__finally </FONT></FONT><FONT face=新宋体><FONT color=#007700>{ <BR></FONT><FONT color=#0000bb>00401043</FONT><FONT color=#007700>: </FONT><FONT color=#0000bb>MOV DWORD PTR SS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>EBP</FONT><FONT color=#007700>-</FONT><FONT color=#0000bb>4</FONT><FONT color=#007700>],</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>ESI <BR>00401046</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>CALL 0040104D <BR>0040104B</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>JMP 00401080 <BR>0040104D</FONT><FONT color=#007700>: </FONT><FONT color=#0000bb>PUSH OFFSET </FONT></FONT><FONT face=新宋体><FONT color=#dd0000>"2: In Finally" <BR></FONT><FONT color=#0000bb>00401052</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>CALL printf <BR>00401057</FONT><FONT color=#007700>: </FONT><FONT color=#0000bb>ADD ESP</FONT><FONT color=#007700>,</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>4 <BR>0040105A</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>RETN <BR></FONT><FONT color=#007700><</FONT><FONT color=#0000bb>FONT color</FONT><FONT color=#007700>=</FONT><FONT color=#0000bb>black</FONT></FONT><FONT face=新宋体><FONT color=#007700>>;} <BR><</FONT><FONT color=#0000bb>FONT color</FONT><FONT color=#007700>=</FONT><FONT color=#0000bb>black</FONT></FONT><FONT face=新宋体><FONT color=#007700>>; } <BR><</FONT><FONT color=#0000bb>FONT color</FONT><FONT color=#007700>=</FONT><FONT color=#0000bb>black</FONT><FONT color=#007700>>; </FONT><FONT color=#0000bb>__except</FONT></FONT><FONT face=新宋体><FONT color=#007700>( <BR></FONT><FONT color=#0000bb>0040105B</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>JMP 00401080 <BR>0040105D</FONT><FONT color=#007700>: </FONT><FONT color=#0000bb>PUSH OFFSET </FONT></FONT><FONT face=新宋体><FONT color=#dd0000>"3: In Filter" <BR></FONT><FONT color=#0000bb>00401062</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>CALL printf <BR>00401067</FONT><FONT color=#007700>: </FONT><FONT color=#0000bb>ADD ESP</FONT><FONT color=#007700>,</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>4 <BR>0040106A</FONT><FONT color=#007700>: </FONT><FONT color=#0000bb>MOV EAX</FONT><FONT color=#007700>,</FONT><FONT color=#0000bb>1 </FONT><FONT color=#007700>; </FONT><FONT color=#0000bb>EXCEPTION_EXECUTE_HANDLER </FONT><FONT color=#007700>= </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>1 <BR>0040106F</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>RETN <BR></FONT><FONT color=#007700>;, </FONT><FONT color=#0000bb>EXCEPTION_EXECUTE_HANDLER </FONT></FONT><FONT face=新宋体 color=#007700>) <BR>; } <BR>; </FONT><FONT face=新宋体><FONT color=#0000bb>the exception handler funtion <BR>00401070</FONT><FONT color=#007700>: </FONT><FONT color=#0000bb>MOV ESP</FONT><FONT color=#007700>,</FONT><FONT color=#0000bb>DWORD PTR SS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>EBP</FONT><FONT color=#007700>-</FONT><FONT color=#0000bb>18</FONT></FONT><FONT face=新宋体><FONT color=#007700>] <BR></FONT><FONT color=#0000bb>00401073</FONT><FONT color=#007700>: </FONT><FONT color=#0000bb>PUSH OFFSET </FONT></FONT><FONT face=新宋体><FONT color=#dd0000>"4: In Exception Handler" <BR></FONT><FONT color=#0000bb>00401078</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>CALL printf <BR>0040107D</FONT><FONT color=#007700>: </FONT><FONT color=#0000bb>ADD ESP</FONT><FONT color=#007700>,</FONT></FONT><FONT face=新宋体 color=#0000bb>4 <BR></FONT><FONT face=新宋体><FONT color=#007700>; } <BR></FONT><FONT color=#0000bb>00401080</FONT><FONT color=#007700>: </FONT><FONT color=#0000bb>MOV DWORD PTR SS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>EBP</FONT><FONT color=#007700>-</FONT><FONT color=#0000bb>4</FONT><FONT color=#007700>],-</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>1 <BR>0040108C</FONT><FONT color=#007700>: XOR </FONT><FONT color=#0000bb>EAX</FONT><FONT color=#007700>,</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>EAX <BR></FONT><FONT color=#007700>; </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>restore previous SEH <BR>0040108E</FONT><FONT color=#007700>: </FONT><FONT color=#0000bb>MOV ECX</FONT><FONT color=#007700>,</FONT><FONT color=#0000bb>DWORD PTR SS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>EBP</FONT><FONT color=#007700>-</FONT><FONT color=#0000bb>10</FONT></FONT><FONT face=新宋体><FONT color=#007700>] <BR></FONT><FONT color=#0000bb>00401091</FONT><FONT color=#007700>: </FONT><FONT color=#0000bb>MOV DWORD PTR FS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>0</FONT><FONT color=#007700>],</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>ECX <BR>00401098</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>POP EDI <BR>00401099</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>POP ESI <BR>0040109A</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>POP EBX <BR>0040109B</FONT><FONT color=#007700>: </FONT><FONT color=#0000bb>MOV ESP</FONT><FONT color=#007700>,</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>EBP <BR>0040109D</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>POP EBP <BR>0040109E</FONT><FONT color=#007700>: </FONT></FONT><FONT color=#0000bb><FONT face=新宋体>RETN</FONT><BR></FONT></FONT></CODE></TD></TR></TBODY></TABLE>建立一个控制台工程,连接并执行先前的文件,观察结果。<BR><BR>Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>1</FONT></FONT><FONT face=新宋体 color=#007700>: </FONT><FONT face=新宋体><FONT color=#0000bb>Raise an Exception <BR>3</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>In Filter <BR>2</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>In Finally <BR>4</FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体 color=#0000bb>In Exception Handler <BR>_<BR></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>程序执行了一个异常的表达式printf("3: In Filter\n");,当异常发生,(在这个例子INT 3 异常,你也能用另外<BR><BR>的异常),在OD中Debugging options->Exceptions你能看到不同类型异常的清单<BR><BR><IMG alt="" src="http://www.codeproject.com/system/inject2exe/ollydbg_exceptions.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0> <BR><BR>5.3.1 Implement Exception Handler<BR><BR>我们希望建立一个异常处理来到达程序的OEP,借助前满的代码,你现在已经能区别SEH安装,异常抛<BR><BR>出,异常表达式过滤,为了建立我们的异常接近(OEP),我们需要下面的代码<BR><BR>SEH installation<BR>Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>LEA EAX</FONT></FONT><FONT face=新宋体><FONT color=#007700>,[</FONT><FONT color=#0000bb>EBP</FONT><FONT color=#007700>+</FONT><FONT color=#0000bb>_except_handler1_OEP_Jump</FONT></FONT><FONT face=新宋体 color=#007700>] <BR></FONT><FONT face=新宋体><FONT color=#0000bb>PUSH EAX <BR>PUSH DWORD PTR FS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>0</FONT></FONT><FONT face=新宋体><FONT color=#007700>] <BR></FONT><FONT color=#0000bb>MOV DWORD PTR FS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>0</FONT><FONT color=#007700>],</FONT></FONT><FONT face=新宋体 color=#0000bb>ESP<BR></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>异常抛出<BR><BR>Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>INT 3<BR></FONT></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>异常表达式过滤<BR>Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>except_handler1_OEP_Jump</FONT></FONT><FONT face=新宋体 color=#007700>: <BR></FONT><FONT face=新宋体><FONT color=#0000bb>PUSH EBP <BR>MOV EBP</FONT><FONT color=#007700>,</FONT></FONT><FONT face=新宋体 color=#0000bb>ESP <BR></FONT><FONT face=新宋体><FONT color=#007700>... <BR></FONT><FONT color=#0000bb>MOV EAX</FONT><FONT color=#007700>, </FONT><FONT color=#0000bb>EXCEPTION_CONTINUE_SEARCH </FONT></FONT><FONT face=新宋体 color=#ff8000>// EXCEPTION_CONTINUE_SEARCH = 0 <BR></FONT><FONT face=新宋体 color=#0000bb>LEAVE <BR>RETN</FONT><FONT face=新宋体 color=#007700></<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>所以我们利用ASM嵌套来到达OEP<BR><BR>Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>__try </FONT></FONT><FONT face=新宋体 color=#ff8000>// SEH installation <BR></FONT><FONT face=新宋体 color=#007700>{ <BR></FONT><FONT face=新宋体 color=#0000bb>__asm <BR></FONT><FONT face=新宋体><FONT color=#007700>{ <BR></FONT><FONT color=#0000bb>INT 3 </FONT></FONT><FONT face=新宋体 color=#ff8000>// An Exception Raise <BR></FONT><FONT face=新宋体><FONT color=#007700>} <BR>} <BR></FONT><FONT color=#0000bb>__except</FONT><FONT color=#007700>( ..., </FONT><FONT color=#0000bb>EXCEPTION_CONTINUE_SEARCH </FONT></FONT><FONT face=新宋体 color=#007700>){} <BR></FONT><FONT face=新宋体 color=#ff8000>// Exception handler expression filter<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>ASM代码<BR><BR>Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>;</FONT></FONT><FONT face=新宋体><FONT color=#007700>---------------------------------------------------- <BR>; </FONT><FONT color=#0000bb>the structured exception handler </FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>SEH</FONT><FONT color=#007700>) </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>installation <BR></FONT><FONT color=#007700>; </FONT><FONT color=#0000bb>__try </FONT></FONT><FONT face=新宋体><FONT color=#007700>{ <BR></FONT><FONT color=#0000bb>LEA EAX</FONT><FONT color=#007700>,[</FONT><FONT color=#0000bb>EBP</FONT><FONT color=#007700>+</FONT><FONT color=#0000bb>_except_handler1_OEP_Jump</FONT></FONT><FONT face=新宋体 color=#007700>] <BR></FONT><FONT face=新宋体><FONT color=#0000bb>PUSH EAX <BR>PUSH DWORD PTR FS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>0</FONT></FONT><FONT face=新宋体><FONT color=#007700>] <BR></FONT><FONT color=#0000bb>MOV DWORD PTR FS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>0</FONT><FONT color=#007700>],</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>ESP <BR></FONT><FONT color=#007700><</FONT><FONT color=#0000bb>FONT color</FONT><FONT color=#007700>=</FONT><FONT color=#0000bb>green</FONT></FONT><FONT face=新宋体 color=#007700>>; ---------------------------------------------------- <BR>; </FONT><FONT face=新宋体 color=#0000bb>the raise a INT 3 exception <BR>INT 3 <BR>INT 3 <BR>INT 3 <BR>INT 3 <BR></FONT><FONT face=新宋体><FONT color=#007700>; } <BR>; </FONT><FONT color=#0000bb>__except</FONT></FONT><FONT face=新宋体 color=#007700>( ... <BR>; ---------------------------------------------------- <BR>; </FONT><FONT face=新宋体 color=#0000bb>exception handler expression filter <BR>_except_handler1_OEP_Jump</FONT><FONT face=新宋体 color=#007700>: <BR></FONT><FONT face=新宋体><FONT color=#0000bb>PUSH EBP <BR>MOV EBP</FONT><FONT color=#007700>,</FONT></FONT><FONT face=新宋体 color=#0000bb>ESP <BR></FONT><FONT face=新宋体><FONT color=#007700>... <BR></FONT><FONT color=#0000bb>MOV EAX</FONT><FONT color=#007700>, </FONT><FONT color=#0000bb>EXCEPTION_CONTINUE_SEARCH </FONT><FONT color=#007700>; </FONT><FONT color=#0000bb>EXCEPTION_CONTINUE_SEARCH </FONT><FONT color=#007700>= </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>0 <BR>LEAVE <BR>RETN <BR>;</FONT><FONT color=#007700>, </FONT><FONT color=#0000bb>EXCEPTION_CONTINUE_SEARCH </FONT></FONT><FONT face=新宋体 color=#007700>) { }<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>异常值__except(..., Value), 定义了这个异常如何被处理,他能由三个值分别是1,0,-1。为了理解他们<BR><BR>请在MSDN Library中寻找有关<A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/key_s-z_4.asp" target=_blank>try-except</A> 声明的描述。当我们把他设置为0时,就不会执行异常处理的功能,<BR><BR>因此,借助于这个值,异常处理就会被忽略,并且线程继续执行其他的代码。<BR><BR><B>如何安装SEH</B> <BR><BR>就像你从前面的代码中看到的,SEH是借助于FS段寄存器还完成安装的。WIN32使用FS段寄存器作为主线<BR><BR>程中数据块的指针。开始的0X1C字节包含Thread Information Block (TIB)的信息,此外,FS:[00h] 在与主线程<BR><BR>的ExceptionList 有关(表三),在我们的代码中,我们已经将_except_handler1_OEP_Jump指针压入堆栈,<BR><BR>并改变ExceptionList, FS:[00h]的值为堆栈起始的值,ESP<BR><BR>线程信息块(TIB)<BR><BR>Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>typedef struct _NT_TIB32 </FONT></FONT><FONT face=新宋体><FONT color=#007700>{ <BR></FONT><FONT color=#0000bb>DWORD ExceptionList</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORD StackBase</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORD StackLimit</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORD SubSystemTib</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>union </FONT></FONT><FONT face=新宋体><FONT color=#007700>{ <BR></FONT><FONT color=#0000bb>DWORD FiberData</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORD Version</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR>}; <BR></FONT><FONT color=#0000bb>DWORD ArbitraryUserPointer</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORD Self</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR>} </FONT><FONT color=#0000bb>NT_TIB32</FONT><FONT color=#007700>, *</FONT><FONT color=#0000bb>PNT_TIB32</FONT></FONT><FONT face=新宋体 color=#007700>;<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR><B>表三</B> FS段寄存器和线程信息块<BR><IMG alt="" src="http://images.blogcn.com/2006/3/5/2/goblinbest,2006030524331.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0><BR><BR><B>5.3.2借助于调整线程间的关系获得OEP</B> <BR><BR><BR>在这部分,我们将完成OEP的接近,并改变线程间的关系,忽略每个简单的异常处理。让线程在先前的<BR><BR>OEP中继续执行代码。当产生异常时,进程间的关系就被保存在堆栈中,借助EXCEPTION_POINTERS,我<BR><BR>们能访问ContextRecord的指针。ContextRecord拥有CONTEXT的数据结构(表四),这便是在执行时间中<BR><BR>的线程间的关系。当我们使用 EXCEPTION_CONTINUE_SEARCH (0)来忽略异常时,指令指针间的关系也<BR><BR>被设置到ContextRecord,以便程序可以返回先前的环境中去。因此,如果我们改变 Win32 Thread Context<BR><BR>中的EIP,使其为开始的OEP,这便可以进入OEP。<BR><BR>表四<BR><IMG alt="" src="http://images.blogcn.com/2006/3/5/2/goblinbest,200603053715.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0><BR><IMG alt="" src="http://images.blogcn.com/2006/3/5/2/goblinbest,200603053838.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0><BR><BR>Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>MOV EAX</FONT></FONT><FONT face=新宋体 color=#007700>, </FONT><FONT face=新宋体><FONT color=#0000bb>ContextRecord <BR>MOV EDI</FONT><FONT color=#007700>, </FONT><FONT color=#0000bb>dwOEP</FONT><FONT color=#007700>; </FONT><FONT color=#0000bb>EAX </FONT><FONT color=#007700><- </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>dwOEP <BR>MOV DWORD PTR DS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>EAX</FONT><FONT color=#007700>+</FONT><FONT color=#0000bb>0B8h</FONT><FONT color=#007700>], </FONT><FONT color=#0000bb>EDI </FONT><FONT color=#007700>; </FONT><FONT color=#0000bb>pContext</FONT><FONT color=#007700>.</FONT><FONT color=#0000bb>Eip </FONT><FONT color=#007700><- </FONT></FONT><FONT face=新宋体 color=#0000bb>EAX<BR></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR><B>WIN32线程间关系的数据结构</B> <BR><BR>Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR></FONT><FONT face=新宋体><FONT color=#ff8000>#define MAXIMUM_SUPPORTED_EXTENSION512 <BR><BR></FONT><FONT color=#0000bb>typedef struct _CONTEXT </FONT></FONT><FONT face=新宋体 color=#007700>{ <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//----------------------------------------- <BR></FONT><FONT color=#0000bb>DWORD ContextFlags</FONT></FONT><FONT face=新宋体 color=#007700>; <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//----------------------------------------- <BR></FONT><FONT color=#0000bb>DWORDDr0</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDDr1</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDDr2</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDDr3</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDDr6</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDDr7</FONT></FONT><FONT face=新宋体 color=#007700>; <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//----------------------------------------- <BR></FONT><FONT color=#0000bb>FLOATING_SAVE_AREA FloatSave</FONT></FONT><FONT face=新宋体 color=#007700>; <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//----------------------------------------- <BR></FONT><FONT color=#0000bb>DWORDSegGs</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDSegFs</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDSegEs</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDSegDs</FONT></FONT><FONT face=新宋体 color=#007700>; <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//----------------------------------------- <BR></FONT><FONT color=#0000bb>DWORDEdi</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDEsi</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDEbx</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDEdx</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDEcx</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDEax</FONT></FONT><FONT face=新宋体 color=#007700>; <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//----------------------------------------- <BR></FONT><FONT color=#0000bb>DWORDEbp</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDEip</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDSegCs</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDEFlags</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDEsp</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDSegSs</FONT></FONT><FONT face=新宋体 color=#007700>; <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//----------------------------------------- <BR></FONT><FONT color=#0000bb>BYTEExtendedRegisters</FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>MAXIMUM_SUPPORTED_EXTENSION</FONT></FONT><FONT face=新宋体 color=#007700>]; <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//---------------------------------------- <BR></FONT><FONT color=#007700>} </FONT><FONT color=#0000bb>CONTEXT</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR>*</FONT><FONT color=#0000bb>LPCONTEXT</FONT></FONT><FONT face=新宋体 color=#007700>;<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>用下面的代码,我们就能使用异常处理程序来到达OEP<BR><BR>Code:
<TABLE cellSpacing=1 cellPadding=8 width="95%" align=center bgColor=#000000 border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><CODE><FONT color=#000000><FONT color=#0000bb><BR><FONT face=新宋体>__stdcall void DynLoader</FONT></FONT><FONT face=新宋体 color=#007700>() <BR>{ <BR></FONT><FONT face=新宋体 color=#0000bb>_asm <BR></FONT><FONT face=新宋体 color=#007700>{ <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//---------------------------------- <BR></FONT><FONT color=#0000bb>DWORD_TYPE</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>DYN_LOADER_START_MAGIC</FONT></FONT><FONT face=新宋体 color=#007700>) <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//---------------------------------- <BR></FONT><FONT color=#0000bb>Main_0</FONT></FONT><FONT face=新宋体><FONT color=#007700>: <BR></FONT><FONT color=#0000bb>PUSHAD</FONT></FONT><FONT face=新宋体 color=#ff8000>// Save the registers context in stack <BR></FONT><FONT face=新宋体 color=#0000bb>CALL Main_1 <BR>Main_1</FONT><FONT face=新宋体 color=#007700>: <BR></FONT><FONT face=新宋体><FONT color=#0000bb>POP EBP <BR>SUB EBP</FONT><FONT color=#007700>,</FONT><FONT color=#0000bb>OFFSET Main_1 </FONT></FONT><FONT face=新宋体><FONT color=#ff8000>// Get Base EBP <BR></FONT><FONT color=#0000bb>MOV EAX</FONT><FONT color=#007700>,</FONT><FONT color=#0000bb>DWORD PTR </FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>EBP</FONT><FONT color=#007700>+</FONT><FONT color=#0000bb>_RO_dwImageBase</FONT></FONT><FONT face=新宋体><FONT color=#007700>] <BR></FONT><FONT color=#0000bb>ADD EAX</FONT><FONT color=#007700>,</FONT><FONT color=#0000bb>DWORD PTR </FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>EBP</FONT><FONT color=#007700>+</FONT><FONT color=#0000bb>_RO_dwOrgEntryPoint</FONT></FONT><FONT face=新宋体><FONT color=#007700>] <BR></FONT><FONT color=#0000bb>MOV DWORD PTR </FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>ESP</FONT><FONT color=#007700>+</FONT><FONT color=#0000bb>10h</FONT><FONT color=#007700>],</FONT><FONT color=#0000bb>EAX</FONT></FONT><FONT face=新宋体><FONT color=#ff8000>// pStack.Ebx <- EAX <BR></FONT><FONT color=#0000bb>LEA EAX</FONT><FONT color=#007700>,[</FONT><FONT color=#0000bb>EBP</FONT><FONT color=#007700>+</FONT><FONT color=#0000bb>_except_handler1_OEP_Jump</FONT></FONT><FONT face=新宋体><FONT color=#007700>] <BR></FONT><FONT color=#0000bb>MOV DWORD PTR </FONT><FONT color=#007700>[</FONT><FONT color=#0000bb>ESP</FONT><FONT color=#007700>+</FONT><FONT color=#0000bb>1Ch</FONT><FONT color=#007700>],</FONT><FONT color=#0000bb>EAX</FONT></FONT><FONT face=新宋体><FONT color=#ff8000>// pStack.Eax <- EAX <BR></FONT><FONT color=#0000bb>POPAD</FONT></FONT><FONT face=新宋体 color=#ff8000>// Restore the first registers context from stack <BR>//---------------------------------------------------- <BR>// the structured exception handler (SEH) installation <BR></FONT><FONT face=新宋体><FONT color=#0000bb>PUSH EAX <BR></FONT><FONT color=#007700>XOR</FONT><FONT color=#0000bb>EAX</FONT><FONT color=#007700>, </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>EAX <BR>PUSH DWORD PTR FS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>0</FONT><FONT color=#007700>]</FONT></FONT><FONT face=新宋体><FONT color=#ff8000>// NT_TIB32.ExceptionList <BR></FONT><FONT color=#0000bb>MOV DWORD PTR FS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>0</FONT><FONT color=#007700>],</FONT><FONT color=#0000bb>ESP</FONT></FONT><FONT face=新宋体><FONT color=#ff8000>// NT_TIB32.ExceptionList <-ESP <BR>//---------------------------------------------------- <BR>// the raise a INT 3 exception <BR></FONT><FONT color=#0000bb>DWORD_TYPE</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>0xCCCCCCCC</FONT></FONT><FONT face=新宋体 color=#007700>) <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//-------------------------------------------------------- <BR>// -------- exception handler expression filter ---------- <BR></FONT><FONT color=#0000bb>_except_handler1_OEP_Jump</FONT></FONT><FONT face=新宋体 color=#007700>: <BR></FONT><FONT face=新宋体><FONT color=#0000bb>PUSH EBP <BR>MOV EBP</FONT><FONT color=#007700>,</FONT></FONT><FONT face=新宋体 color=#0000bb>ESP <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//------------------------------ <BR></FONT><FONT color=#0000bb>MOV EAX</FONT><FONT color=#007700>,</FONT><FONT color=#0000bb>DWORD PTR SS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>EBP</FONT><FONT color=#007700>+</FONT><FONT color=#0000bb>010h</FONT><FONT color=#007700>]</FONT></FONT><FONT face=新宋体 color=#ff8000>// PCONTEXT: pContext <- EAX <BR>//============================== <BR></FONT><FONT face=新宋体 color=#0000bb>PUSH EDI <BR></FONT><FONT face=新宋体><FONT color=#ff8000>// restore original SEH <BR></FONT><FONT color=#0000bb>MOV EDI</FONT><FONT color=#007700>,</FONT><FONT color=#0000bb>DWORD PTR DS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>EAX</FONT><FONT color=#007700>+</FONT><FONT color=#0000bb>0C4h</FONT><FONT color=#007700>]</FONT></FONT><FONT face=新宋体><FONT color=#ff8000>// pContext.Esp <BR></FONT><FONT color=#0000bb>PUSH DWORD PTR DS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>EDI</FONT></FONT><FONT face=新宋体><FONT color=#007700>] <BR></FONT><FONT color=#0000bb>POP DWORD PTR FS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>0</FONT></FONT><FONT face=新宋体><FONT color=#007700>] <BR></FONT><FONT color=#0000bb>ADD DWORD PTR DS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>EAX</FONT><FONT color=#007700>+</FONT><FONT color=#0000bb>0C4h</FONT><FONT color=#007700>],</FONT><FONT color=#0000bb>8</FONT></FONT><FONT face=新宋体><FONT color=#ff8000>// pContext.Esp <BR>//------------------------------ <BR>// set the Eip to the OEP <BR></FONT><FONT color=#0000bb>MOV EDI</FONT><FONT color=#007700>,</FONT><FONT color=#0000bb>DWORD PTR DS</FONT><FONT color=#007700>:[</FONT><FONT color=#0000bb>EAX</FONT><FONT color=#007700>+</
