1、前言:为什么要这么做
0 X, h0 \$ z9 O: N: ?% ?很多时候,我们发现一个PE(EXE或DLL)中非常有用且功能独立的函数(call xxxxxxxx),并且已经知道了这个函数的各个入口参数的类型和具体含义,我们想在其他的软件中使用这个函数。于是,我想到了将这个PE中的函数改成一个导出函数,这样,我们就可以在任何软件中通过“LoadLibrary("ThisPE.EXE")”等API来使用这个函数了。
5 j' |+ @# J- y& `8 B# z* l+ [" V+ A0 B. q+ f
在汉化中的应用是可以直接调用游戏中的解包,压包函数来解包,压包,以及访问游戏中的文本显示函数等等。。。
1 h: g; B4 i' w) i* _9 v, B4 T$ j. o
2、技术基础:已经了解PE结构 & G! @* C. g: E9 Q
9 V- G- |5 }. d& p* L" q- ] L3、分类: 7 ~! D; x$ _/ n( U3 I0 x- x* e
(1)有导出表的DLL和EXE文件--非常简单 - |2 B. \4 i2 f( g: u5 G
对于这类PE文件,要简单的多,因为只要修改一下PE中的Export,增加上一个导出函数,并把这个导出函数的入口指向我们要导出的call的调用地址(RVA格式)就可以了。甚至可以更简单的处理:找个不用的导出函数,改一下入口就可以了。 ( ^4 |5 ^4 u i& x1 \0 }- F9 c* \
(2)没有导出表的EXE文件--稍微复杂
! X$ \8 n7 |& `, }' F; \! s1 g因为大部分EXE文件没有导出表,所以我们必须要给它增加一个导出表。其实也很简单,给EXE增加一个节,并在这个节中按照导出表的格式构造一个导出函数,并将这个函数入口指向我们要导出的call的调用地址的RVA,并在PE头中指出其位置和大小。
6 {" ?% W4 X. m
0 Z% m% Z X" o4、举例说明: * J7 o, B# q6 C+ t" r
test.exe:ImageBase=0x00400000
2 O y: W/ k5 u# F1 l+ J发现test.exe 的 0x00408050 处为call 0x0040A012 的 0x0040A012是我们要导出的函数,我们将它导出为MyFunction函数。
- W. V# Y ^ E8 R* K* m, w5 x$ \3 K& F% n. f* w( l- `
(1)给test.exe增加一个节:RVA=0x28000,size=0x1000 ( }5 h- v1 U" q; | X9 s* z( j
(2)构造导出表:
& e/ ~8 k0 l0 t4 q$ g( W# \4 hMy_Export_Table dd 0 ;Characteristics
; e& N4 N$ N7 ?8 g: a2 ZMy_TimeDateStamp dd 0 ;TimeDateStamp 5 f6 u, h p( k7 \: e; J
dw 0 ;MajorVersion 5 B9 o# y3 M. I4 b. n0 ~
dw 0 ;MinorVersion 3 d4 x% k6 Y8 p2 d+ j. B
My_nName dd My_DLL_nName-ImageBase ;nName 1 O& c7 F# b" v, {; k* x
dd 1 ;nBase
8 p4 H Y* {# _- ?7 {5 R* C" qdd 1 ;NumberOfFunctions + U. B! ^; A( \. j& I
dd 1 ;NumberOfNames # u# Z+ g' E6 G/ i7 J5 A
My_AddressOfFunctions dd 0x0040A012-ImageBase ;AddressOfFunctions 5 U8 i3 `! P& H, U+ e; q+ p1 R
My_AddressOfNames dd My_Fun_Name-ImageBase ;AddressOfNames
& G, q! [5 V4 M! n4 ^9 h# A, VMy_AddressOfNameOrdinals dd 0 ;AddressOfNameOrdinals # N( e) z; G; l5 b g
--------------------------------------------------------------------- . Z0 T$ j) y+ q) T
My_Fun_Name db 'MyFunction',0
# n. p- G$ }+ }4 ZMy_DLL_nName db 'test.exe',0 " a1 }. W. U, \. q
! B# @5 U) v( n0 c6 @- R
(3)LoadPe修改PE头,将导出表地址填入0x28000,大小填入0x1000,保存。
6 Q' f0 w3 E( x$ B1 T% }
; o% [8 u9 u5 D* Y% v$ gSpirng.W/2005.3.14 4 h B4 }( F$ p3 }" A6 v3 v
# n4 {2 Z4 _$ D& [# E2 d( k' |% A
. {( F+ }% B W/ D-------------------------------------------------------------------------------- |