1、前言:为什么要这么做
2 p9 u. R0 B' N* m很多时候,我们发现一个PE(EXE或DLL)中非常有用且功能独立的函数(call xxxxxxxx),并且已经知道了这个函数的各个入口参数的类型和具体含义,我们想在其他的软件中使用这个函数。于是,我想到了将这个PE中的函数改成一个导出函数,这样,我们就可以在任何软件中通过“LoadLibrary("ThisPE.EXE")”等API来使用这个函数了。
9 e$ n! t+ U% f Z4 b3 T3 f/ I0 h+ D- n/ v p1 v
在汉化中的应用是可以直接调用游戏中的解包,压包函数来解包,压包,以及访问游戏中的文本显示函数等等。。。! H& ]/ I: O k
' N3 }7 P4 F! }
2、技术基础:已经了解PE结构
, X& P& K/ g* Z$ u/ H( S
8 l) u9 }. Q% G7 W0 A( x3 l3、分类:
{) ^) F; ~4 X- `3 Q(1)有导出表的DLL和EXE文件--非常简单 ' n2 U' e8 d* ]' K7 f B/ {
对于这类PE文件,要简单的多,因为只要修改一下PE中的Export,增加上一个导出函数,并把这个导出函数的入口指向我们要导出的call的调用地址(RVA格式)就可以了。甚至可以更简单的处理:找个不用的导出函数,改一下入口就可以了。 7 {2 e& @' M! r& Z8 u! ?5 A# G/ n
(2)没有导出表的EXE文件--稍微复杂
* }% t1 T: G5 y& O7 l* c2 A因为大部分EXE文件没有导出表,所以我们必须要给它增加一个导出表。其实也很简单,给EXE增加一个节,并在这个节中按照导出表的格式构造一个导出函数,并将这个函数入口指向我们要导出的call的调用地址的RVA,并在PE头中指出其位置和大小。
, c8 v' x8 s, T# A u9 M0 C& T. ^2 W; A
4、举例说明: ! T! J, |( W- `" ?- u+ A
test.exe:ImageBase=0x00400000 L% }9 D! U8 c3 V; x1 L
发现test.exe 的 0x00408050 处为call 0x0040A012 的 0x0040A012是我们要导出的函数,我们将它导出为MyFunction函数。
9 U. `- B. ^( j( D5 F& U8 Q
/ h% Q3 r6 Z. ]" A9 u(1)给test.exe增加一个节:RVA=0x28000,size=0x1000
% p" n/ R9 q0 g' @* v7 L; @(2)构造导出表: / T4 N" E7 C; ~0 H( O) m
My_Export_Table dd 0 ;Characteristics
) Z& z7 s& Q! T) k. ]. \My_TimeDateStamp dd 0 ;TimeDateStamp , v; T# R/ z1 V9 ^2 S6 K3 ^: w4 M
dw 0 ;MajorVersion 1 ~5 U3 s4 @# v3 n+ e; s$ \& h! j
dw 0 ;MinorVersion - x$ j0 a% ~$ q' \
My_nName dd My_DLL_nName-ImageBase ;nName
! \2 G7 c' F# s# [0 F! Gdd 1 ;nBase A* }$ I1 \% y. Q2 s' N
dd 1 ;NumberOfFunctions ) Z- N- n, l1 _1 n- Q
dd 1 ;NumberOfNames
& D! }% `$ i. a) ]% d1 zMy_AddressOfFunctions dd 0x0040A012-ImageBase ;AddressOfFunctions 0 g$ w: m9 j, H |
My_AddressOfNames dd My_Fun_Name-ImageBase ;AddressOfNames
" {# N5 A$ v( \( Z0 n9 @/ VMy_AddressOfNameOrdinals dd 0 ;AddressOfNameOrdinals
6 G' L; M' s4 m$ F5 E+ L3 e, [7 R--------------------------------------------------------------------- 6 ]( J+ @) ^+ O( Q2 ^7 w8 B" z3 J( b ]
My_Fun_Name db 'MyFunction',0 $ {; ~& b6 ^: D4 }( c
My_DLL_nName db 'test.exe',0
8 D: |5 V# Q. N* R2 W. l6 y4 B* l) V G% X: A2 P' w
(3)LoadPe修改PE头,将导出表地址填入0x28000,大小填入0x1000,保存。 * t% M! V# A. k* r. P7 t
2 g# g7 ~- }3 H& p# U! j% a* RSpirng.W/2005.3.14
) h1 I& V3 P/ J7 Y7 s) s
( ^; A5 ^! a2 X2 Z5 m+ Y q" B3 c* C, `+ n% b1 u0 J6 J
-------------------------------------------------------------------------------- |