dllproxyskel使用起来比较简单,dllproxyskel自动从你输入的原始DLL中提取所有导出函数符号" Y! d3 y. P4 t# J5 r2 o
然后按一定的格式生成.c文件,自动将所有的dll函数信息记录进.def, 做好替换 函数在.c,
% I) b# U. Z/ k r; U; X3 t2 F: e6 @通过在.c文件中#ifdef DLL_PATH 来寻找原始DLL路径(默认为\\system32),原始DLL里的函数调用是原函数名前面加个下划线_% v) ]; t! X1 b' F
比如Exttextout,在.c里做完自己的事后可以调用 _Exttextout 来完全其原本的工作. s$ |' R! w* b# @0 [9 X+ h
* W0 w q( p+ x4 T命令行输入0 _; A% s0 m9 t$ T* [. ~8 X: F
dllproxyskel.exe <input.dll>7 h3 \$ T' \1 ?4 ^" n
- open file D:\\项目\\dllproxyskel\\input.dll
. A& v* W( U6 Z % _! G2 F I6 B+ [! ^
3 v% U/ `) Y5 i& K4 Z$ d
------------------------------------------------------------------ u; {. s- w1 a* S* m `3 t
我们需要额外添加的代码
/ Q9 I7 O6 K* ~) p#define _WINGDI_ //这个值从wingdi.h里获取,仅仅在代理系统DLL的时候需要
. d, _3 Q) j7 u3 q8 {//定义了两种声明代理函数的宏,CALL_FUNCTION与CALL_FUNCTION2
6 B- K/ K1 f: \* r" |2 w. K//这里我采用第二种,将返回值与函数名与参数列表一起作为宏内容,下面第一个参数BOOL 是ExtTextOutA的返回值$ c4 X% F8 ]$ X4 y- R( D% E
CALL_FUNCTION2(BOOL, ExtTextOutA,7 W- `% n2 x* J) K: z* |4 |. c8 d
HDC hdc,. y; z+ Q0 ?. s& e0 D I
INT x,: m$ ^5 S. ~6 [1 m+ w
INT y,$ ]% O( K4 ]' l4 H
UINT flags, w* D4 K9 q& g8 e) L; Y- i
const RECT* lprect,$ b% h' v6 ?/ q1 F1 ?
LPCSTR str,
7 L7 H4 C% E. e# f- L UINT count,# [7 f% U1 u. i. @) _- [+ A
const INT* lpDx
& O( q$ l/ g4 k1 L: d, B) {
8 Z7 S' _+ k+ e" T { //这里可以做任何你想做的事了,HOOK成功
1 P. @ ?& H2 F7 x" [, n2 X' h outputdebugstr("HOOK ExtTextOutA suscess!");
6 Z+ Z9 s6 k+ p9 V6 ~: ?! T BOOL result = _ExtTextOutA(x, y, flags, lprect, str,count,lpDx);//调用原始函数
" l6 ^3 k: Z1 Q return(result);
7 b$ c0 q; m* Y* c}
( m6 f# I5 ~3 t1 y3 m+ h) r. R+ a O% `
注意,生成的代码需要用gcc/mingw来编译,+ S0 C+ m! k3 r8 L
主要是因为其中使用了gcc宏扩展
: T9 [- f( ]# N4 J#define CALLING_CONVENTION WINAPI // default for Windows DLLs$ q# H* _ Y2 h1 A& I* w
#define PROXY_FUNCTION(FUNCTION_NAME) /* for the proxified functions not modified */ \\' Y9 K1 v e% N3 N
void CALLING_CONVENTION FUNCTION_NAME(void)2 a$ ~2 k, u* ]: ?) q" X0 D
#define PROXY_FUNCTIONX(FUNCTION_NAME) \\2 i; s$ F2 {8 H. w
static PROXY_FUNCTION(*_##FUNCTION_NAME) = NULL; \\
7 |$ c* c# d J9 V Q, C1 n: Q5 P PROXY_FUNCTION(FUNCTION_NAME) { \\; U% [1 l) j* M3 H. D
POP_EBP __asm__("jmp *__"#FUNCTION_NAME); \\% h& N h, q) ?+ l) ?
}# }! M( U( W* k9 Y" d- O0 V/ c; Z
#define CALL_FUNCTION(FUNCTION_NAME) \\
1 Y8 U- i( u+ ]9 d3 E' K u static CALLING_CONVENTION FUNCTION_NAME##_(*_##FUNCTION_NAME) = NULL; \\
$ n$ \. [( N& Q8 g& |, F8 a! I CALLING_CONVENTION FUNCTION_NAME##_(FUNCTION_NAME)- A1 |* }5 O, J. ]4 O7 W" Z
#define CALL_FUNCTION2(FUNCTION_RET, FUNCTION_NAME, FUNCTION_ARGS ...) \\
% e2 x+ N; E: T8 U- Y( l J( n static CALLING_CONVENTION FUNCTION_RET (*_##FUNCTION_NAME)(FUNCTION_ARGS) = NULL; \\
o j. Q0 w6 Q" I/ g CALLING_CONVENTION FUNCTION_RET FUNCTION_NAME(FUNCTION_ARGS)/ s, p9 V X* b; } S
) Q* O/ E7 u1 u ^- k- W
1 X! a& w- @" ?7 D8 B等我回头翻译到VC里
& c+ B/ j8 e7 t" F& y+ P- O: }) Q' `待续 |