dllproxyskel使用起来比较简单,dllproxyskel自动从你输入的原始DLL中提取所有导出函数符号( ^9 W; ] t. g9 s3 D& F* B( @; \
然后按一定的格式生成.c文件,自动将所有的dll函数信息记录进.def, 做好替换 函数在.c,0 O, D9 n* L j# i2 c1 x; `4 P
通过在.c文件中#ifdef DLL_PATH 来寻找原始DLL路径(默认为\\system32),原始DLL里的函数调用是原函数名前面加个下划线_
6 U8 Y5 W) E5 o# c' m比如Exttextout,在.c里做完自己的事后可以调用 _Exttextout 来完全其原本的工作, T4 a! V2 _) [& T9 J+ P5 J
d! M& r; }0 y; I
命令行输入9 t8 E3 _: v8 t8 G" e6 X
dllproxyskel.exe <input.dll>
$ C3 V( p6 h7 y0 m6 N# @+ L' N4 {- open file D:\\项目\\dllproxyskel\\input.dll) i* Y" ~. ]5 Q9 X' G; w1 W
' M9 S0 h% }! b4 t0 l" w
0 b7 z- A+ @& s2 Y7 J% z( L------------------------------------------------------------------" _: X) p0 [) Z6 C% X# n
我们需要额外添加的代码
' p5 Y) y! b3 C4 u2 \- ^#define _WINGDI_ //这个值从wingdi.h里获取,仅仅在代理系统DLL的时候需要
4 B3 Y& C# Z( {% h0 h8 b, v* |//定义了两种声明代理函数的宏,CALL_FUNCTION与CALL_FUNCTION25 S, _& t# o$ }! |1 M+ M
//这里我采用第二种,将返回值与函数名与参数列表一起作为宏内容,下面第一个参数BOOL 是ExtTextOutA的返回值, Z- J* |% c+ i
CALL_FUNCTION2(BOOL, ExtTextOutA,
5 W- `. Q0 C1 | ~3 I0 ?$ k3 |" E# }- O HDC hdc,
5 N+ @" ^, _$ a4 ?6 o0 q- H INT x,5 p( M1 V+ D# J" g h
INT y,
8 b0 r' C$ ?* `1 X! a UINT flags,% H1 ~" |! C+ J- g
const RECT* lprect,6 Q. M0 c( i9 K2 b
LPCSTR str,
' V# [' L. l& E% T7 s- H' j& j UINT count," O4 C0 k% X2 S$ H8 m
const INT* lpDx" D4 d4 @2 z: P# V8 |
) {
0 E n% |2 A& y" @0 e6 I# H //这里可以做任何你想做的事了,HOOK成功
# A! t8 D# r1 O, u3 ~' ?! v! h/ G) @ outputdebugstr("HOOK ExtTextOutA suscess!");
* r2 ?4 x& I5 Q" Z& N8 R BOOL result = _ExtTextOutA(x, y, flags, lprect, str,count,lpDx);//调用原始函数. i: R1 E$ Z- `# s( @
return(result);9 S0 b5 C; ~% g/ N) g
}+ y% k3 b& b. L; l6 R- _5 M1 s5 Y9 W
, \3 r. P$ V, @! \6 }5 b2 `; V
注意,生成的代码需要用gcc/mingw来编译,7 }4 v% c. s/ ], C4 T0 x0 {
主要是因为其中使用了gcc宏扩展# {7 F5 T/ |( a1 i5 f! [+ X
#define CALLING_CONVENTION WINAPI // default for Windows DLLs
( G( a( C4 d! [: G( K; ]0 C#define PROXY_FUNCTION(FUNCTION_NAME) /* for the proxified functions not modified */ \\
+ q6 |; y7 w K9 u void CALLING_CONVENTION FUNCTION_NAME(void) k$ W$ O$ B0 s! M& u
#define PROXY_FUNCTIONX(FUNCTION_NAME) \\! X, ]+ ~! v9 L: ~$ Q
static PROXY_FUNCTION(*_##FUNCTION_NAME) = NULL; \\' f2 i+ M. }) I# B: y) i% [5 c
PROXY_FUNCTION(FUNCTION_NAME) { \\
$ e/ i- [" y. g* X" I) D2 |: b POP_EBP __asm__("jmp *__"#FUNCTION_NAME); \\
$ m, P% }2 W' j0 V/ G Q! g }
, v4 h9 r% G' Y: o p. g#define CALL_FUNCTION(FUNCTION_NAME) \\
) O7 d, S0 f6 `7 j3 l static CALLING_CONVENTION FUNCTION_NAME##_(*_##FUNCTION_NAME) = NULL; \\
$ j& `7 f0 C; D) U8 S$ {- q CALLING_CONVENTION FUNCTION_NAME##_(FUNCTION_NAME)
* `! y- S d! X/ d#define CALL_FUNCTION2(FUNCTION_RET, FUNCTION_NAME, FUNCTION_ARGS ...) \\% W# T& O$ Y2 X& V% n
static CALLING_CONVENTION FUNCTION_RET (*_##FUNCTION_NAME)(FUNCTION_ARGS) = NULL; \\/ I: ~9 \5 [/ p& l+ X( S
CALLING_CONVENTION FUNCTION_RET FUNCTION_NAME(FUNCTION_ARGS)
5 S- E2 r3 _0 J3 n. f* g
# O N: ^% q0 F8 e7 ]8 f4 u' ], \
, Y+ f' t1 ^% V- s等我回头翻译到VC里
8 l/ E1 Q7 t& f2 V待续 |