dllproxyskel使用起来比较简单,dllproxyskel自动从你输入的原始DLL中提取所有导出函数符号
5 v) }3 r! p& q4 F# R" ]然后按一定的格式生成.c文件,自动将所有的dll函数信息记录进.def, 做好替换 函数在.c,
/ G* [! f. b) ]5 ?$ Y6 P通过在.c文件中#ifdef DLL_PATH 来寻找原始DLL路径(默认为\\system32),原始DLL里的函数调用是原函数名前面加个下划线_ e* D1 B4 D _% i8 t/ D
比如Exttextout,在.c里做完自己的事后可以调用 _Exttextout 来完全其原本的工作4 l3 d1 S$ Y6 N
+ p! j) u T$ f) g3 o2 l. g
命令行输入4 o1 g) o7 a: z# z8 G/ u& h
dllproxyskel.exe <input.dll>1 x7 n* M0 f4 p
- open file D:\\项目\\dllproxyskel\\input.dll
! m% w6 w: E9 u 7 G' [- a( Z( [; q
@: A2 @( _0 f$ I! |: N& `
------------------------------------------------------------------
% K" D, S, p, c9 P$ Z4 C- V我们需要额外添加的代码
4 U* i/ s B9 s$ v$ ]8 ]! a#define _WINGDI_ //这个值从wingdi.h里获取,仅仅在代理系统DLL的时候需要
# @ ~% h R4 s% e" x//定义了两种声明代理函数的宏,CALL_FUNCTION与CALL_FUNCTION2' k7 y1 N4 t/ u5 C( ^4 R6 O. D
//这里我采用第二种,将返回值与函数名与参数列表一起作为宏内容,下面第一个参数BOOL 是ExtTextOutA的返回值* j* U$ @( D/ \
CALL_FUNCTION2(BOOL, ExtTextOutA,7 b4 _6 |* \ m- u8 c2 `; A
HDC hdc,. a/ k& o5 Z+ f* G# J
INT x,! s/ a |# }0 D
INT y,
- G5 n6 T- J9 o. o UINT flags,) b# s4 G" _/ U8 B# o4 g
const RECT* lprect,
. s2 A1 T8 v0 {7 x# x9 M2 n LPCSTR str,6 H. o! J7 Q. m" k
UINT count,
4 q6 x; i5 S. M) {2 v const INT* lpDx
1 h; @( G8 J: A9 O) L% I! k) {% `% F- F0 J4 Y
//这里可以做任何你想做的事了,HOOK成功) t! i9 h1 b4 \- Q0 Y8 d7 n
outputdebugstr("HOOK ExtTextOutA suscess!");
8 R9 F/ B" x6 y5 b* J BOOL result = _ExtTextOutA(x, y, flags, lprect, str,count,lpDx);//调用原始函数
. o5 ?" `+ f8 Z' `0 t+ K1 Q return(result);& n+ J9 Z- D y7 u* p3 u0 h3 m
}" C- E. Y* c$ n
- v% F2 {8 y) n5 ~" f4 ?
注意,生成的代码需要用gcc/mingw来编译,
( s2 @2 @+ ~; g4 N6 b% y, X主要是因为其中使用了gcc宏扩展
/ |" p/ W4 `; o+ c3 _#define CALLING_CONVENTION WINAPI // default for Windows DLLs
! W( B2 B# P$ k ~! @3 K#define PROXY_FUNCTION(FUNCTION_NAME) /* for the proxified functions not modified */ \\
. u* q- |; [: m+ Y* E) P' }7 I2 ? void CALLING_CONVENTION FUNCTION_NAME(void)7 R- i* v) X+ v6 r7 i8 c
#define PROXY_FUNCTIONX(FUNCTION_NAME) \\& L8 W4 f/ w7 Q
static PROXY_FUNCTION(*_##FUNCTION_NAME) = NULL; \\: a# B( r* i+ _4 P. i& I6 A
PROXY_FUNCTION(FUNCTION_NAME) { \\8 X' D7 [0 \$ ?" |+ N
POP_EBP __asm__("jmp *__"#FUNCTION_NAME); \\
/ Y' ?, P2 m, q4 R( A' q, O }2 F5 D$ Q* o5 A f
#define CALL_FUNCTION(FUNCTION_NAME) \\
) Q' \) O4 r4 L static CALLING_CONVENTION FUNCTION_NAME##_(*_##FUNCTION_NAME) = NULL; \\5 X! c: l5 K7 S* R# T$ }
CALLING_CONVENTION FUNCTION_NAME##_(FUNCTION_NAME)
* N: l0 x/ U2 b- M% V6 l' s9 i#define CALL_FUNCTION2(FUNCTION_RET, FUNCTION_NAME, FUNCTION_ARGS ...) \\+ D6 p5 ~+ @; w$ H& r' C" h) A. s: @+ O
static CALLING_CONVENTION FUNCTION_RET (*_##FUNCTION_NAME)(FUNCTION_ARGS) = NULL; \\! Z) u# g) T2 l Q
CALLING_CONVENTION FUNCTION_RET FUNCTION_NAME(FUNCTION_ARGS)
, _; J' t- _( N" N9 u, `8 H# x) B% J
! u5 [' M' k7 g N2 E8 o
等我回头翻译到VC里
: o3 i/ U' t. M; Z待续 |