dllproxyskel使用起来比较简单,dllproxyskel自动从你输入的原始DLL中提取所有导出函数符号' D3 Q# K. x- g t( }8 I( M- p
然后按一定的格式生成.c文件,自动将所有的dll函数信息记录进.def, 做好替换 函数在.c,- ?5 _% J7 j g+ y4 r O
通过在.c文件中#ifdef DLL_PATH 来寻找原始DLL路径(默认为\\system32),原始DLL里的函数调用是原函数名前面加个下划线_) G! L, T* _. |9 F- C7 t
比如Exttextout,在.c里做完自己的事后可以调用 _Exttextout 来完全其原本的工作8 f) h; ]3 w5 b% ]
R8 T8 _( t6 u命令行输入6 H4 S3 J* u" `/ |- Q
dllproxyskel.exe <input.dll>
: z) l' y' ]7 a' @- open file D:\\项目\\dllproxyskel\\input.dll" j1 ]) ]# Y/ j$ u+ M
& H6 M5 d4 c% G7 e, b
# T2 z; e0 N$ j" S/ }------------------------------------------------------------------% n8 `$ l. b$ `5 P
我们需要额外添加的代码
, T6 `; k ]/ d" L#define _WINGDI_ //这个值从wingdi.h里获取,仅仅在代理系统DLL的时候需要
7 z/ i5 E. Y. \1 T& O& [1 a//定义了两种声明代理函数的宏,CALL_FUNCTION与CALL_FUNCTION2. _7 S, x& o# d# o
//这里我采用第二种,将返回值与函数名与参数列表一起作为宏内容,下面第一个参数BOOL 是ExtTextOutA的返回值
- N2 p, I- Q8 ~4 ^CALL_FUNCTION2(BOOL, ExtTextOutA,3 { U+ Z3 ~) A5 C& C
HDC hdc,
. p& \8 g7 `; I# z INT x,2 v+ {' L9 j: R8 \6 B2 ~- m- k
INT y,
: m# U6 U& n" ]8 l; t/ W: t UINT flags,4 n9 f. M6 W: c( v1 w5 e, D
const RECT* lprect,
1 o1 B) Q o( [! A. U3 w/ a LPCSTR str,2 `. t9 N& W+ H
UINT count,7 M) L5 G8 q# j& ?3 [8 W* V
const INT* lpDx
$ }7 e4 d- X( E( r0 y3 \) {
3 }4 ?6 Z+ k* q4 X3 ~ //这里可以做任何你想做的事了,HOOK成功
$ t0 y- m5 U0 k& T& t! l outputdebugstr("HOOK ExtTextOutA suscess!");* O. Z; L* g. h
BOOL result = _ExtTextOutA(x, y, flags, lprect, str,count,lpDx);//调用原始函数
$ z, f. k, y- A& C* E& G5 b return(result);) k' L Q! `2 Z& V& }- a
}6 v9 Q2 E ?! l& w4 W
5 f3 y1 Q) K+ k6 \' Y% C' l/ C注意,生成的代码需要用gcc/mingw来编译,
/ I t9 c# s$ R7 r主要是因为其中使用了gcc宏扩展
( G# ?+ Y- R( \" n#define CALLING_CONVENTION WINAPI // default for Windows DLLs
* S8 @, h6 W7 ?) }' a5 }1 I#define PROXY_FUNCTION(FUNCTION_NAME) /* for the proxified functions not modified */ \\
' c3 A6 f( V: [# g8 G- e4 K' |6 [ void CALLING_CONVENTION FUNCTION_NAME(void)
0 {9 [6 L/ @& {$ y( N#define PROXY_FUNCTIONX(FUNCTION_NAME) \\& R6 k* v O) ^+ Q0 V
static PROXY_FUNCTION(*_##FUNCTION_NAME) = NULL; \\: O4 n( [: s% r6 O7 G0 c! u
PROXY_FUNCTION(FUNCTION_NAME) { \\& I, u8 M9 z% e$ ^; q
POP_EBP __asm__("jmp *__"#FUNCTION_NAME); \\/ `' V5 L; S) z' P8 g. E+ H' R
}' ?) E; x- `7 f, v
#define CALL_FUNCTION(FUNCTION_NAME) \\3 K1 G9 Y _& u+ U% K; w
static CALLING_CONVENTION FUNCTION_NAME##_(*_##FUNCTION_NAME) = NULL; \\
3 _: Y/ J9 X2 W% O h9 Q, w' K CALLING_CONVENTION FUNCTION_NAME##_(FUNCTION_NAME)" ~ g: A! W* ^; u! W+ t" Y3 q
#define CALL_FUNCTION2(FUNCTION_RET, FUNCTION_NAME, FUNCTION_ARGS ...) \\' W4 G7 R( e) h. S
static CALLING_CONVENTION FUNCTION_RET (*_##FUNCTION_NAME)(FUNCTION_ARGS) = NULL; \\
& f, m u) N0 R5 E L* a CALLING_CONVENTION FUNCTION_RET FUNCTION_NAME(FUNCTION_ARGS)
. J+ Y) J& u+ R l2 H: ]6 w
. X" ~4 B f4 M. k; I; t# Z) U
5 M8 U g b0 G& }4 h+ F等我回头翻译到VC里
! e8 p7 Z1 }, O6 h9 i8 v. |6 s待续 |