[转载]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>+</FONT><FONT color=#0000bb>0A4h</FONT><FONT color=#007700>] </FONT></FONT><FONT face=新宋体><FONT color=#ff8000>// EAX <- pContext.Ebx <BR></FONT><FONT color=#0000bb>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><FONT face=新宋体 color=#ff8000>// pContext.Eip <- EAX <BR>//------------------------------ <BR></FONT><FONT face=新宋体 color=#0000bb>POP EDI <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//============================== <BR></FONT><FONT color=#0000bb>MOV EAX</FONT><FONT color=#007700>, </FONT></FONT><FONT face=新宋体 color=#0000bb>EXCEPTION_CONTINUE_SEARCH <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 color=#007700><FONT face=新宋体>} <BR>}</FONT><BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR> <STRONG>6.构建一个引入表,并重建开始的引入表</STRONG> <BR><BR><BR>我们有两种方法在应用程序中使用DLL文件:<BR><B><BR>.通过额外的支持使用库文件</B><BR><BR><IMG alt="" src="http://www.codeproject.com/system/inject2exe/dependencies.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0> <BR><BR><B>.在运行时间中使用DLL文件</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>// DLL function signature <BR></FONT><FONT color=#0000bb>typedef HGLOBAL </FONT><FONT color=#007700>(*</FONT><FONT color=#0000bb>importFunction_GlobalAlloc</FONT><FONT color=#007700>)(</FONT><FONT color=#0000bb>UINT</FONT><FONT color=#007700>, </FONT><FONT color=#0000bb>SIZE_T</FONT></FONT><FONT face=新宋体><FONT color=#007700>); <BR>... <BR></FONT><FONT color=#0000bb>importFunction_GlobalAlloc __GlobalAlloc</FONT></FONT><FONT face=新宋体 color=#007700>; <BR><BR></FONT><FONT face=新宋体><FONT color=#ff8000>// Load DLL file <BR></FONT><FONT color=#0000bb>HINSTANCE hinstLib </FONT><FONT color=#007700>= </FONT><FONT color=#0000bb>LoadLibrary</FONT><FONT color=#007700>(</FONT><FONT color=#dd0000>"Kernel32.dll"</FONT></FONT><FONT face=新宋体><FONT color=#007700>); <BR>if (</FONT><FONT color=#0000bb>hinstLib </FONT><FONT color=#007700>== </FONT><FONT color=#0000bb>NULL</FONT></FONT><FONT face=新宋体 color=#007700>) <BR>{ <BR></FONT><FONT face=新宋体 color=#ff8000>// Error - unable to load DLL <BR></FONT><FONT face=新宋体 color=#007700>} <BR><BR></FONT><FONT face=新宋体><FONT color=#ff8000>// Get function pointer <BR></FONT><FONT color=#0000bb>__GlobalAlloc </FONT></FONT><FONT face=新宋体><FONT color=#007700>= <BR>(</FONT><FONT color=#0000bb>importFunction_GlobalAlloc</FONT><FONT color=#007700>)</FONT><FONT color=#0000bb>GetProcAddress</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>hinstLib</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#dd0000>"GlobalAlloc"</FONT></FONT><FONT face=新宋体><FONT color=#007700>); <BR>if (</FONT><FONT color=#0000bb>addNumbers </FONT><FONT color=#007700>== </FONT><FONT color=#0000bb>NULL</FONT></FONT><FONT face=新宋体 color=#007700>) <BR>{ <BR></FONT><FONT face=新宋体 color=#ff8000>// Error - unable to find DLL function <BR></FONT><FONT face=新宋体><FONT color=#007700>} <BR><BR></FONT><FONT color=#0000bb>FreeLibrary</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>hinstLib</FONT></FONT><FONT face=新宋体 color=#007700>);<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>当你建立一个WINDOWS应用程序的工程,连接器至少包括kernel32.dll,没有kernel32.dll文件中的<BR><BR>LoadLibrary()和GetProcAddress()函数我们就不能在运行时间中装载DLL文件,所依赖的信息被储存在引入表<BR><BR>的节区内。如果利用Dependency Walker,我们将很容易的观察DLL模块,以及那些被引入PE文件的重要<BR><BR>功能。<BR><BR><IMG alt="" src="http://www.codeproject.com/system/inject2exe/dependency_walker.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0> <BR><BR>我打算建立我们自定义的引入表来管理我们的工程,我们必须修改原来的引入表,以便于运行程序中真<BR><BR>正的代码。<BR><B><BR>PE Maker - Step 3</B> <BR><BR><A href="http://www.codeproject.com/system/inject2exe/pemaker3.zip" target=_blank>Download source files - 65.4 Kb </A><BR><B><BR>6.1构件客户端引入表</B> <BR><BR>我建议你读一下6.4节<A href="http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx" target=_blank>Microsoft Portable Executable and the Common Object File Format Specification </A><BR><BR>文挡,这节包含了重要的知识来让你了解引入表的性能。<BR><BR>利用optional header 中的第二页数据,便可得到引入表数据。因此,你能用下面的代码获得他<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 dwVirtualAddress </FONT></FONT><FONT face=新宋体><FONT color=#007700>= </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_IMPORT</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><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_IMPORT</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><BR><BR>The VirtualAddress refers to structures by IMAGE_IMPORT_DESCRIPTOR. This structure contains the pointer to <BR><BR>the imported DLL name and the relative virtual address of the first thunk(抱歉,THUNK我不知道该如何翻译,<BR><BR>所以我无法理解这段的含义 <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=新宋体>typedef struct _IMAGE_IMPORT_DESCRIPTOR </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>DWORDCharacteristics</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDOriginalFirstThunk</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR>}; <BR></FONT><FONT color=#0000bb>DWORDTimeDateStamp</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDForwarderChain</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORD</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>Name</FONT><FONT color=#007700></</FONT><FONT color=#0000bb>FONT</FONT><FONT color=#007700>>;</FONT></FONT><FONT face=新宋体><FONT color=#ff8000>// the imported DLL name <BR></FONT><FONT color=#0000bb>DWORD</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>FirstThunk</FONT><FONT color=#007700></</FONT><FONT color=#0000bb>FONT</FONT><FONT color=#007700>>;</FONT></FONT><FONT face=新宋体><FONT color=#ff8000>// the relative virtual address of the first thunk <BR></FONT><FONT color=#007700>} </FONT><FONT color=#0000bb>IMAGE_IMPORT_DESCRIPTOR</FONT><FONT color=#007700>, *</FONT><FONT color=#0000bb>PIMAGE_IMPORT_DESCRIPTOR</FONT></FONT><FONT face=新宋体 color=#007700>;<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>When a program is running, the Windows task manager sets the thunks by the virtual address of the function. The <BR><BR>virtual address is found by the name of the function. At first, the thunks hold the relative virtual address of the <BR><BR>function name, Table 5; during execution, they are fixed up by the virtual address of the functions, Table 6.<BR><BR><B>表五--在文件映像中的引入表</B> <BR><BR><IMG alt="" src="http://images.blogcn.com/2006/3/5/2/goblinbest,2006030533725.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0><BR><BR><B>表六--在虚拟内存中的引入表</B> <BR><BR><IMG alt="" src="http://images.blogcn.com/2006/3/5/2/goblinbest,2006030534229.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0><BR><BR>我想制作一个简单的引入表来引入Kernel32.dll中的LoadLibrary(),和 GetProcAddress() 函数,在运行时间中我<BR><BR>要用这两个基本的API函数来覆盖其他的API函数。下面的ASM代码将展示实现他是多么的容易。<BR><BR><IMG alt="" src="http://images.blogcn.com/2006/3/5/2/goblinbest,2006030535458.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0><BR><BR><B>运行后.....</B> <BR><BR><IMG alt="" src="http://images.blogcn.com/2006/3/5/2/goblinbest,2006030535251.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0><BR><BR> <STRONG>6</STRONG>
<P><FONT face="verdana, tahoma, helvetica" size=2>我已经准备了一个类库来制作每个引入表,这将借助于字符串。CITMaker类库在itmaker.h中,他将使用<BR><BR>sz_IT_EXE_strings 来建立一个引入表,以及一个相对虚拟地址引入表。<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=#007700>static const </FONT><FONT color=#0000bb>char </FONT><FONT color=#007700>*</FONT><FONT color=#0000bb>sz_IT_EXE_strings</FONT></FONT><FONT face=新宋体><FONT color=#007700>[]= <BR>{ <BR></FONT><FONT color=#dd0000>"Kernel32.dll"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#dd0000>"LoadLibraryA"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#dd0000>"GetProcAddress"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#0000bb>0</FONT></FONT><FONT face=新宋体><FONT color=#007700>,, <BR></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>下面我使用这个类库来建立引入表以支持DLL和OCX,所以这是一个常规库来表现所有可能的引入表。下<BR><BR>个一步骤,我用下面的代码来完成。<BR><BR><IMG alt="" src="http://images.blogcn.com/2006/3/5/3/goblinbest,200603054925.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0> <BR><BR><B>6.2在运行时间内使用其他的API函数</B> <BR><BR>在这次,我们使用LoadLibrary() 和GetProcAddress()来装载其他的DLL文件,找出其他的API函数的进程地<BR><BR>址。<BR><BR><IMG alt="" src="http://images.blogcn.com/2006/3/5/3/goblinbest,2006030542026.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0> <BR><BR>我想有一个完善的被引入函数表,类似于一个真正执行中的EXE文件,如果你看一下一个PE文件的内<BR><BR>部,你将发现API的调用是API函数在虚拟地址间的间接跳转完成的。<BR><B><BR>JMP DWORD PTR [XXXXXXXX]</B> <BR><BR><IMG alt="" src="http://images.blogcn.com/2006/3/5/3/goblinbest,2006030542925.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0> <BR><BR>借助于这个性能我们可以很容易的扩展我们工程的其他部分 ,因此我们建立两个数据表,一个是API函<BR><BR>数,另一个是JMP [XXXXXXXX]<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=新宋体 color=#ff8000>#define __jmp_apibyte_type(0xFF) byte_type(0x25) <BR></FONT><FONT face=新宋体 color=#0000bb>__asm <BR></FONT><FONT face=新宋体 color=#007700>{ <BR>... <BR></FONT><FONT face=新宋体><FONT color=#ff8000>//---------------------------------------------------------------- <BR></FONT><FONT color=#0000bb>_p_GetModuleHandle</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>_p_VirtualProtect</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>_p_GetModuleFileName</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>_p_CreateFile</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>_p_GlobalAlloc</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>_jmp_GetModuleHandle</FONT><FONT color=#007700>:</FONT><FONT color=#0000bb>__jmp_apidword_type</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>0xCCCCCCCC</FONT></FONT><FONT face=新宋体><FONT color=#007700>) <BR></FONT><FONT color=#0000bb>_jmp_VirtualProtect</FONT><FONT color=#007700>:</FONT><FONT color=#0000bb>__jmp_apidword_type</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>0xCCCCCCCC</FONT></FONT><FONT face=新宋体><FONT color=#007700>) <BR></FONT><FONT color=#0000bb>_jmp_GetModuleFileName</FONT><FONT color=#007700>:</FONT><FONT color=#0000bb>__jmp_apidword_type</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>0xCCCCCCCC</FONT></FONT><FONT face=新宋体><FONT color=#007700>) <BR></FONT><FONT color=#0000bb>_jmp_CreateFile</FONT><FONT color=#007700>:</FONT><FONT color=#0000bb>__jmp_apidword_type</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>0xCCCCCCCC</FONT></FONT><FONT face=新宋体><FONT color=#007700>) <BR></FONT><FONT color=#0000bb>_jmp_GlobalAlloc</FONT><FONT color=#007700>:</FONT><FONT color=#0000bb>__jmp_apidword_type</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>0xCCCCCCCC</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>下面的代码我们来安装自定义的引入表<BR><BR><IMG alt="" src="http://images.blogcn.com/2006/3/5/3/goblinbest,2006030543715.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0> <BR><BR><B>6.3修复最初的引入表</B> <BR><BR>In order to run the program again, we should fix up the thunks of the actual import table, otherwise we have a <BR><BR>corrupted target PE file. Our code must correct all of the thunks the same as Table 5 to Table 6. Once more, <BR><BR>LoadLibrary() and GetProcAddress() aid us in our effort to reach our intention.(8会翻译,抱歉)<BR><BR><IMG alt="" src="http://images.blogcn.com/2006/3/5/3/goblinbest,2006030545537.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/3/goblinbest,200603054579.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0></FONT></P> <STRONG>7.支持DLL和OCX</STRONG> <BR><BR>下面我将把DLL和OCX加入我们的PE工程中,如果我们注意到两次到达入口点的偏移地址,客户引入表,<BR><BR>重新调整后的表的话,要支持他们是很容易的事。<BR><BR><B>PE Maker - Step 4</B> <BR><BR><A href="http://www.codeproject.com/system/inject2exe/pemaker4.zip" target=_blank>Download source files - 68.6 Kb</A> <BR><BR><B>7.1 Twice OEP approach</B> <BR><BR>DLL或着OCX文件的入口点偏移最少要被主程序接触两次:<BR><BR><B>.构造[B] <BR><BR>当一个DLL文件被LoadLibrary()函数装载,或者通过调用 DllRegisterServer()函数使用LoadLibaray()和<BR><BR>GetProcAddress() 函数对一个OCX文件注册,第一次到达OEP就完成了。<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=新宋体>hinstDLL </FONT></FONT><FONT face=新宋体><FONT color=#007700>= </FONT><FONT color=#0000bb>LoadLibrary</FONT><FONT color=#007700>( </FONT><FONT color=#dd0000>"test1.dll" </FONT></FONT><FONT face=新宋体 color=#007700>);<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=新宋体>hinstOCX </FONT></FONT><FONT face=新宋体><FONT color=#007700>= </FONT><FONT color=#0000bb>LoadLibrary</FONT><FONT color=#007700>( </FONT><FONT color=#dd0000>"test1.ocx" </FONT></FONT><FONT face=新宋体><FONT color=#007700>); <BR></FONT><FONT color=#0000bb>_DllRegisterServer </FONT><FONT color=#007700>= </FONT><FONT color=#0000bb>GetProcAddress</FONT><FONT color=#007700>( </FONT><FONT color=#0000bb>hinstOCX</FONT><FONT color=#007700>, </FONT><FONT color=#dd0000>"DllRegisterServer" </FONT></FONT><FONT face=新宋体><FONT color=#007700>); <BR></FONT><FONT color=#0000bb>_DllRegisterServer</FONT><FONT color=#007700>(); </FONT></FONT><FONT face=新宋体 color=#ff8000>// ocx register<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>[B].Destructor(破坏)</B> <BR><BR>当主程序使用FreeLibrary()函数释放库文件,就会第二次到达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=新宋体>FreeLibrary</FONT></FONT><FONT face=新宋体><FONT color=#007700>( </FONT><FONT color=#0000bb>hinstDLL </FONT></FONT><FONT face=新宋体 color=#007700>);<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=新宋体>FreeLibrary</FONT></FONT><FONT face=新宋体><FONT color=#007700>( </FONT><FONT color=#0000bb>hinstOCX </FONT></FONT><FONT face=新宋体 color=#007700>);<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR><BR><BR><BR>To perform this, I have employed a trick, that causes in the second time again, the instruction pointer (EIP) traveling <BR><BR>owards the original OEP by the structured exception handler.(抱歉8会翻译)<BR><BR><IMG alt="" src="http://images.blogcn.com/2006/3/5/3/goblinbest,2006030552111.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0><BR><BR>我希望在前面的代码中你已经掌握了那个技巧,但是那还不够,我们还要考虑映像基址(ImageBase)的问<BR><BR>题,当库文件被主程序载入不同映像基址我们应该写一些代码来找到真正的映像基址,记住他并在将来<BR><BR>利用他。<BR><BR><IMG alt="" src="http://images.blogcn.com/2006/3/5/3/goblinbest,2006030552439.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0><BR><BR>借助于观察堆栈信息,这个代码找到真正的映像基址。通过使用真正的和形式上的映像基址映像基址,<BR><BR>我们要修正程序内部所有的内存调用,不要对此担心,通过重新调整表的信息就可以轻松的完成。<BR><BR><B>7.2 对表进行重新调整</B> <BR><BR>为了更好的了解重置表(relocation table ),你应该看一看6.6节中<A href="http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx" target=_blank>Microsoft Portable Executable and <BR><BR>Common Object File Format Specification</A> 文档的内容。重置表包含许多package来包含在虚拟内存映像中虚拟<BR><BR>地址的相关信息。每一个package包含一个8bit的报头以显示虚拟地址基址和数据的数量。下面我用<BR><BR>IMAGE_BASE_RELOCATION的数据结构来说明。<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 _IMAGE_BASE_RELOCATION </FONT></FONT><FONT face=新宋体><FONT color=#007700>{ <BR></FONT><FONT color=#0000bb>DWORDVirtualAddress</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDSizeOfBlock</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR>} </FONT><FONT color=#0000bb>IMAGE_BASE_RELOCATION</FONT><FONT color=#007700>, *</FONT><FONT color=#0000bb>PIMAGE_BASE_RELOCATION</FONT></FONT><FONT face=新宋体 color=#007700>;<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR><B>表七</B> <BR><IMG alt="" src="http://images.blogcn.com/2006/3/5/9/goblinbest,2006030516192.jpg" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0> <BR><BR><B>表七</B> 表现了重置表的主要概念。此外你能在OD中装载一个DLL或OCX文件来观察重置表,在内存映<BR><BR>射窗口中便可观察到".reloc" 节区。使用我们工程中的下面代码,你能找到重置表的位置。<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 dwVirtualAddress </FONT></FONT><FONT face=新宋体><FONT color=#007700>= </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_BASERELOC</FONT></FONT><FONT face=新宋体><FONT color=#007700>]. <BR></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><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_BASERELOC</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><BR><BR>借助于OD的Long Hex viewer模式,我们可以看到,在这个例子中虚拟内存基址是0x1000,块大小是<BR><BR>0x184。<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=新宋体>008E1000 </FONT></FONT><FONT face=新宋体 color=#007700>: </FONT><FONT face=新宋体><FONT color=#0000bb>00001000000001843016300030403028 <BR>008E1010 </FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>30683054308C308030AC309C30D830CC <BR>008E1020 </FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>30E030DC30E830E430F030EC310030F4 <BR>008E1030 </FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>3120310D315F315031A431A031C031A8 <BR>008E1040 </FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>31D031CC31F431EC31FC31F832043200 <BR>008E1050 </FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>320C320832143210324C322C32583254 <BR>008E1060 </FONT><FONT color=#007700>: </FONT></FONT><FONT face=新宋体 color=#0000bb>3260325C326832643270326C32B03274<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=新宋体>0x1000 </FONT></FONT><FONT face=新宋体><FONT color=#007700>+ </FONT><FONT color=#0000bb>0x0000 </FONT><FONT color=#007700>= </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>0x1000 <BR>0x1000 </FONT><FONT color=#007700>+ </FONT><FONT color=#0000bb>0x0016 </FONT><FONT color=#007700>= </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>0x1016 <BR>0x1000 </FONT><FONT color=#007700>+ </FONT><FONT color=#0000bb>0x0028 </FONT><FONT color=#007700>= </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>0x1028 <BR>0x1000 </FONT><FONT color=#007700>+ </FONT><FONT color=#0000bb>0x0040 </FONT><FONT color=#007700>= </FONT></FONT><FONT face=新宋体><FONT color=#0000bb>0x1040 <BR>0x1000 </FONT><FONT color=#007700>+ </FONT><FONT color=#0000bb>0x0054 </FONT><FONT color=#007700>= </FONT></FONT><FONT face=新宋体 color=#0000bb>0x1054<BR></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>每个package使用其内部连续的4字节表格来完成表的重置.第一个字节与重置表的类型有关,下面的连续三<BR><BR>个字节是那些必须用来纠正映像信息的虚拟地址基址和映像基址的偏移.<BR><BR><IMG alt="" src="http://images.blogcn.com/2006/3/5/9/goblinbest,2006030516519.jpg" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0> <BR><BR><B>我所指的类型是什么?</B> <BR><BR>我所说的类型是以下一系列值的一个:<BR><BR>.IMAGE_REL_BASED_ABSOLUTE (0):不操作(NO effect)<BR><BR>.IMAGE_REL_BASED_HIGH (1):重新部署虚拟地址和偏移地址的高十六字节。<BR><BR>.IMAGE_REL_BASED_LOW (2):重新部署虚拟地址和偏移地址的低十六字节。<BR><BR>.IMAGE_REL_BASED_HIGHLOW (3): 重新部署虚拟地址和偏移地址。<BR><BR><B>在重新部署是都做了什么?</B> <BR><BR>通过重新部署,借助".reloc"节区packageS按照现在的映像基址,虚拟内存中的一些值被纠正。<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=新宋体>delta_ImageBase </FONT></FONT><FONT face=新宋体><FONT color=#007700>= </FONT><FONT color=#0000bb>current_ImageBase </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><FONT face=新宋体 color=#0000bb>ImageBase<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=新宋体>mem</FONT></FONT><FONT face=新宋体><FONT color=#007700>[ </FONT><FONT color=#0000bb>current_ImageBase </FONT><FONT color=#007700>+ </FONT><FONT color=#0000bb>0x1000 </FONT></FONT><FONT face=新宋体><FONT color=#007700>] = <BR></FONT><FONT color=#0000bb>mem</FONT><FONT color=#007700>[ </FONT><FONT color=#0000bb>current_ImageBase </FONT><FONT color=#007700>+ </FONT><FONT color=#0000bb>0x1000 </FONT><FONT color=#007700>] + </FONT><FONT color=#0000bb>delta_ImageBase </FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>mem</FONT><FONT color=#007700>[ </FONT><FONT color=#0000bb>current_ImageBase </FONT><FONT color=#007700>+ </FONT><FONT color=#0000bb>0x1016 </FONT></FONT><FONT face=新宋体><FONT color=#007700>] = <BR></FONT><FONT color=#0000bb>mem</FONT><FONT color=#007700>[ </FONT><FONT color=#0000bb>current_ImageBase </FONT><FONT color=#007700>+ </FONT><FONT color=#0000bb>0x1016 </FONT><FONT color=#007700>] + </FONT><FONT color=#0000bb>delta_ImageBase </FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>mem</FONT><FONT color=#007700>[ </FONT><FONT color=#0000bb>current_ImageBase </FONT><FONT color=#007700>+ </FONT><FONT color=#0000bb>0x1028 </FONT></FONT><FONT face=新宋体><FONT color=#007700>] = <BR></FONT><FONT color=#0000bb>mem</FONT><FONT color=#007700>[ </FONT><FONT color=#0000bb>current_ImageBase </FONT><FONT color=#007700>+ </FONT><FONT color=#0000bb>0x1028 </FONT><FONT color=#007700>] + </FONT><FONT color=#0000bb>delta_ImageBase </FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>mem</FONT><FONT color=#007700>[ </FONT><FONT color=#0000bb>current_ImageBase </FONT><FONT color=#007700>+ </FONT><FONT color=#0000bb>0x1040 </FONT></FONT><FONT face=新宋体><FONT color=#007700>] = <BR></FONT><FONT color=#0000bb>mem</FONT><FONT color=#007700>[ </FONT><FONT color=#0000bb>current_ImageBase </FONT><FONT color=#007700>+ </FONT><FONT color=#0000bb>0x1040 </FONT><FONT color=#007700>] + </FONT><FONT color=#0000bb>delta_ImageBase </FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>mem</FONT><FONT color=#007700>[ </FONT><FONT color=#0000bb>current_ImageBase </FONT><FONT color=#007700>+ </FONT><FONT color=#0000bb>0x1054 </FONT></FONT><FONT face=新宋体><FONT color=#007700>] = <BR></FONT><FONT color=#0000bb>mem</FONT><FONT color=#007700>[ </FONT><FONT color=#0000bb>current_ImageBase </FONT><FONT color=#007700>+ </FONT><FONT color=#0000bb>0x1054 </FONT><FONT color=#007700>] + </FONT><FONT color=#0000bb>delta_ImageBase </FONT></FONT><FONT face=新宋体 color=#007700>; <BR>...<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>I have employed the following code from Morphine packer to implement the relocation.(抱歉实在翻译不通顺)<BR><BR><IMG alt="" src="http://images.blogcn.com/2006/3/5/10/goblinbest,20060305184654.jpg" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0> <IMG alt="" src="http://images.blogcn.com/2006/3/5/10/goblinbest,20060305184736.jpg" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0> <BR><BR><B>7.3建立一个特殊的引入表</B> <BR><BR>为了支持 OLE-ActiveX控件注册,我们应该给予目标OCX和DLL文件一个特殊的入口表。<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=#007700>const </FONT><FONT color=#0000bb>char </FONT><FONT color=#007700>*</FONT><FONT color=#0000bb>sz_IT_OCX_strings</FONT></FONT><FONT face=新宋体><FONT color=#007700>[]= <BR>{ <BR></FONT><FONT color=#dd0000>"Kernel32.dll"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#dd0000>"LoadLibraryA"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#dd0000>"GetProcAddress"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#dd0000>"GetModuleHandleA"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#0000bb>0</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#dd0000>"User32.dll"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#dd0000>"GetKeyboardType"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#dd0000>"WindowFromPoint"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#0000bb>0</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#dd0000>"AdvApi32.dll"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#dd0000>"RegQueryValueExA"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#dd0000>"RegSetValueExA"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#dd0000>"StartServiceA"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#0000bb>0</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#dd0000>"Oleaut32.dll"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#dd0000>"SysFreeString"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#dd0000>"CreateErrorInfo"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#dd0000>"SafeArrayPtrOfIndex"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#0000bb>0</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#dd0000>"Gdi32.dll"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#dd0000>"UnrealizeObject"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#0000bb>0</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#dd0000>"Ole32.dll"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#dd0000>"CreateStreamOnHGlobal"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#dd0000>"IsEqualGUID"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#0000bb>0</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#dd0000>"ComCtl32.dll"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#dd0000>"ImageList_SetIconSize"</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#0000bb>0</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></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>缺少这些API函数,库文件就不能装载,此外 DllregisterServer() and DllUregisterServer()也不会起作用。<BR><BR>在CPECryptor::CryptFile中,在新的目标引入表创造时我对DLL和EXE文件做了区别。<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=#007700>if(( </FONT><FONT color=#0000bb>image_nt_headers</FONT><FONT color=#007700>-></FONT><FONT color=#0000bb>FileHeader</FONT><FONT color=#007700>.</FONT></FONT><FONT face=新宋体><FONT color=#0000bb>Characteristics <BR></FONT><FONT color=#007700>& </FONT><FONT color=#0000bb>IMAGE_FILE_DLL </FONT><FONT color=#007700>) == </FONT><FONT color=#0000bb>IMAGE_FILE_DLL </FONT></FONT><FONT face=新宋体><FONT color=#007700>) <BR>{ <BR></FONT><FONT color=#0000bb>ImportTableMaker </FONT><FONT color=#007700>= new </FONT><FONT color=#0000bb>CITMaker</FONT><FONT color=#007700>( </FONT><FONT color=#0000bb>IMPORT_TABLE_OCX </FONT></FONT><FONT face=新宋体><FONT color=#007700>); <BR>} <BR>else <BR>{ <BR></FONT><FONT color=#0000bb>ImportTableMaker </FONT><FONT color=#007700>= new </FONT><FONT color=#0000bb>CITMaker</FONT><FONT color=#007700>( </FONT><FONT color=#0000bb>IMPORT_TABLE_EXE </FONT></FONT><FONT face=新宋体 color=#007700>); <BR><BR>}<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR><B>8.保护线程局部存储</B> <BR><BR>使用线程局部存储(TLS),程序能执行一个线状的进程,这个性能通常被Borland使用:Delphi和C++ <BR><BR>Builder。当你封装一个PE文件,你应该注意保持TLS清空(you should take care to keep clean the TLS),否<BR><BR>则你的packer将不支持Borland Delphi and C++连接成EXE文件。请查阅6.7节的<A href="http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx" target=_blank>Microsoft Portable Executable <BR><BR>and Common Object File Format Specification </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=新宋体>typedef struct _IMAGE_TLS_DIRECTORY32 </FONT></FONT><FONT face=新宋体><FONT color=#007700>{ <BR></FONT><FONT color=#0000bb>DWORDStartAddressOfRawData</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDEndAddressOfRawData</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDAddressOfIndex</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDAddressOfCallBacks</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDSizeOfZeroFill</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR></FONT><FONT color=#0000bb>DWORDCharacteristics</FONT></FONT><FONT face=新宋体><FONT color=#007700>; <BR>} </FONT><FONT color=#0000bb>IMAGE_TLS_DIRECTORY32</FONT><FONT color=#007700>, * </FONT><FONT color=#0000bb>PIMAGE_TLS_DIRECTORY32</FONT></FONT><FONT face=新宋体 color=#007700>;<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>为了保证TLS目录的安全,我把他拷贝到装载者(loader)内部一个特殊的地方<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=#007700>... <BR></FONT><FONT color=#0000bb>_tls_dwStartAddressOfRawData</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>_tls_dwEndAddressOfRawData</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>_tls_dwAddressOfIndex</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>_tls_dwAddressOfCallBacks</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>_tls_dwSizeOfZeroFill</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>_tls_dwCharacteristics</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>...<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR>It is necessary to correct the TLS directory entry in the Optional Header:(entry怕翻译错,这句就看英文把<IMG alt="" src="http://www.ph4nt0m.org/bbs/images/smilies/tongue.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><FONT face=新宋体><FONT color=#007700>if(</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_TLS</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>{ <BR></FONT><FONT color=#0000bb>memcpy</FONT><FONT color=#007700>(&</FONT><FONT color=#0000bb>pDataTable</FONT><FONT color=#007700>-></FONT><FONT color=#0000bb>image_tls_directory</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#0000bb>image_tls_directory</FONT></FONT><FONT face=新宋体><FONT color=#007700>, <BR></FONT><FONT color=#0000bb>sizeof</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>IMAGE_TLS_DIRECTORY32</FONT></FONT><FONT face=新宋体><FONT color=#007700>)); <BR></FONT><FONT color=#0000bb>dwOffset</FONT><FONT color=#007700>=</FONT><FONT color=#0000bb>DWORD</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>pData1</FONT><FONT color=#007700>)-</FONT><FONT color=#0000bb>DWORD</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>pNewSection</FONT></FONT><FONT face=新宋体><FONT color=#007700>); <BR></FONT><FONT color=#0000bb>dwOffset</FONT><FONT color=#007700>+=</FONT><FONT color=#0000bb>sizeof</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>t_DATA_1</FONT><FONT color=#007700>)-</FONT><FONT color=#0000bb>sizeof</FONT><FONT color=#007700>(</FONT><FONT color=#0000bb>IMAGE_TLS_DIRECTORY32</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_TLS</FONT></FONT><FONT face=新宋体><FONT color=#007700>]. <BR></FONT><FONT color=#0000bb>VirtualAddress</FONT><FONT color=#007700>=</FONT><FONT color=#0000bb>dwVirtualAddress </FONT><FONT color=#007700>+ </FONT><FONT color=#0000bb>dwOffset</FONT></FONT><FONT face=新宋体 color=#007700>; <BR>}<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR><B>9.注入你的代码(PS:我已等了很久~~~~~~~~~~)</B> <BR><BR>我已经放置了一个"Hello World!" 的代码<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=新宋体>push MB_OK </FONT></FONT><FONT face=新宋体 color=#007700>| </FONT><FONT face=新宋体><FONT color=#0000bb>MB_ICONINFORMATION <BR>lea eax</FONT><FONT color=#007700>,[</FONT><FONT color=#0000bb>ebp</FONT><FONT color=#007700>+</FONT><FONT color=#0000bb>_p_szCaption</FONT></FONT><FONT face=新宋体 color=#007700>] <BR></FONT><FONT face=新宋体><FONT color=#0000bb>push eax <BR>lea eax</FONT><FONT color=#007700>,[</FONT><FONT color=#0000bb>ebp</FONT><FONT color=#007700>+</FONT><FONT color=#0000bb>_p_szText</FONT></FONT><FONT face=新宋体 color=#007700>] <BR></FONT><FONT face=新宋体 color=#0000bb>push eax <BR>push NULL <BR>call _jmp_MessageBox <BR></FONT><FONT face=新宋体 color=#ff8000>// MessageBox(NULL, szText, szCaption, MB_OK | MB_ICONINFORMATION) ; <BR></FONT><FONT face=新宋体 color=#007700>...<BR></FONT><FONT color=#0000bb></FONT></FONT></CODE></TD></TR></TBODY></TABLE><BR><BR><B>PE Maker - Step 5</B> <BR><BR><A href="http://www.codeproject.com/system/inject2exe/pemaker5.zip" target=_blank>Download source files - 71.7 Kb </A><BR><BR><IMG alt="" src="http://www.codeproject.com/system/inject2exe/helloworld.gif" onload="java script:if(this.width>screen.width-333)this.width=screen.width-333" border=0> <BR><BR><B>10.结论</B> <BR><BR><BR>通过该文你应该知道了把代码注射到PE文件中是多么容易~~~~~~~~(后面的都是废话不翻译了,吼吼~~~~~~~)<BR>
页:
[1]
