1、前言:为什么要这么做 9 w) z* N! X9 Y! d: R3 a) U
很多时候,我们发现一个PE(EXE或DLL)中非常有用且功能独立的函数(call xxxxxxxx),并且已经知道了这个函数的各个入口参数的类型和具体含义,我们想在其他的软件中使用这个函数。于是,我想到了将这个PE中的函数改成一个导出函数,这样,我们就可以在任何软件中通过“LoadLibrary("ThisPE.EXE")”等API来使用这个函数了。
9 t' Y, P( o, }$ N5 S1 Z6 ~5 P. Z5 X" z# D' `9 B( C& F3 ]# b
在汉化中的应用是可以直接调用游戏中的解包,压包函数来解包,压包,以及访问游戏中的文本显示函数等等。。。; l7 K8 L8 E8 M1 ^
5 m, r3 Q0 F, E) Y6 e
2、技术基础:已经了解PE结构 8 S6 g: S: `. x( q( B& h. c- F6 t
6 ^8 P) B' t* ]9 g2 W! J' z
3、分类: - k( o5 w4 w3 n$ k7 b3 W" K
(1)有导出表的DLL和EXE文件--非常简单
1 l! K6 b; \' D对于这类PE文件,要简单的多,因为只要修改一下PE中的Export,增加上一个导出函数,并把这个导出函数的入口指向我们要导出的call的调用地址(RVA格式)就可以了。甚至可以更简单的处理:找个不用的导出函数,改一下入口就可以了。 + \# N; j' G- d
(2)没有导出表的EXE文件--稍微复杂
C' I3 B4 A! @因为大部分EXE文件没有导出表,所以我们必须要给它增加一个导出表。其实也很简单,给EXE增加一个节,并在这个节中按照导出表的格式构造一个导出函数,并将这个函数入口指向我们要导出的call的调用地址的RVA,并在PE头中指出其位置和大小。
+ G1 v" e; I$ [) X( ^4 x' L$ u+ V- F, B4 n+ F2 S+ O6 Y, R2 F
4、举例说明:
; s6 A9 D) ^* h( mtest.exe:ImageBase=0x00400000
3 J5 e% R/ ]9 a, P发现test.exe 的 0x00408050 处为call 0x0040A012 的 0x0040A012是我们要导出的函数,我们将它导出为MyFunction函数。
# V+ A* f4 \6 N% u5 e- O
/ {5 `7 g* [+ _) y" U( r(1)给test.exe增加一个节:RVA=0x28000,size=0x1000
; I2 u" Y, o' {, u. ^% l+ P(2)构造导出表: 9 }! _$ y. `! o4 f) s
My_Export_Table dd 0 ;Characteristics
f) X% e! y( s6 k( V4 dMy_TimeDateStamp dd 0 ;TimeDateStamp
( U) q7 `& f8 I7 Tdw 0 ;MajorVersion
/ a1 [. X* M( c5 K; k" odw 0 ;MinorVersion 2 s0 z. x! w/ D/ _
My_nName dd My_DLL_nName-ImageBase ;nName " A7 q# j f5 K5 U, L
dd 1 ;nBase $ J- h8 G% F+ c. N" G
dd 1 ;NumberOfFunctions
) t# c- f, p7 a' H( K3 mdd 1 ;NumberOfNames
' G% S' h# d/ B4 D: z4 }& eMy_AddressOfFunctions dd 0x0040A012-ImageBase ;AddressOfFunctions ) y& F4 @' t( Q/ n z/ T
My_AddressOfNames dd My_Fun_Name-ImageBase ;AddressOfNames % f/ t: T" }+ s7 r# s9 K Z; t
My_AddressOfNameOrdinals dd 0 ;AddressOfNameOrdinals ! p- F3 `. o( D+ c4 ]$ r+ \3 z$ K
--------------------------------------------------------------------- " ~1 j, Z% Z( ~- G" Q! c& k
My_Fun_Name db 'MyFunction',0 9 r6 z" k1 g" B
My_DLL_nName db 'test.exe',0
, }/ N% y# ^2 `
5 U' u. n! y, F$ i(3)LoadPe修改PE头,将导出表地址填入0x28000,大小填入0x1000,保存。 " S6 m5 ]/ j) Q1 I* C
. t0 E) C* i9 u7 u$ R7 Y. o8 \Spirng.W/2005.3.14
9 n% y0 u8 ^8 |9 k2 U. ~0 [& j) a
1 S) V% ]3 J6 m- p
" F% D& z# C' ^3 f2 `; H-------------------------------------------------------------------------------- |