dllproxyskel使用起来比较简单,dllproxyskel自动从你输入的原始DLL中提取所有导出函数符号
) m% v0 y# R4 a1 q' G然后按一定的格式生成.c文件,自动将所有的dll函数信息记录进.def, 做好替换 函数在.c,% x+ r0 C2 h1 Y: N0 F w0 t! p' B
通过在.c文件中#ifdef DLL_PATH 来寻找原始DLL路径(默认为\\system32),原始DLL里的函数调用是原函数名前面加个下划线_
0 a! a7 C* x2 U0 q比如Exttextout,在.c里做完自己的事后可以调用 _Exttextout 来完全其原本的工作4 ~# G7 ]- V. u: v& E6 r
+ F% e6 g( t# m9 C5 ]8 J
命令行输入 _1 t4 \; v+ G$ q7 h
dllproxyskel.exe <input.dll>
/ t! y( B, ]3 {- open file D:\\项目\\dllproxyskel\\input.dll
7 S7 h8 m3 {# m# E- Y" B5 n& r" u1 Y
3 H$ d! y# z: m4 ]! b: k
' q4 u7 p( R, J$ a; O+ [3 ?------------------------------------------------------------------, I9 d1 m: B9 l9 T0 K6 A8 V
我们需要额外添加的代码
0 A' l r8 S6 w, a#define _WINGDI_ //这个值从wingdi.h里获取,仅仅在代理系统DLL的时候需要7 q8 [0 J. }) X" O4 }7 B
//定义了两种声明代理函数的宏,CALL_FUNCTION与CALL_FUNCTION2
8 w! j7 C- t( O% C' w//这里我采用第二种,将返回值与函数名与参数列表一起作为宏内容,下面第一个参数BOOL 是ExtTextOutA的返回值% k* p1 S& J& t; H" O6 ` p
CALL_FUNCTION2(BOOL, ExtTextOutA,. Q5 |; X4 O8 K3 f- ]. P5 L
HDC hdc,
0 N4 b% h; } t. d0 N" h4 G+ \ INT x,1 M N/ ?$ G5 @$ ], c; {: @9 m
INT y,
) R& _+ ^- S( ?# H UINT flags,
5 E- o" T# y7 a! T const RECT* lprect,
" f: r! U# q1 l9 [' L# P" j LPCSTR str, @9 }+ H( B/ q2 V6 G
UINT count,+ A6 F+ ?. W1 v( h
const INT* lpDx
1 F* }3 t! d [: t7 _3 o: z6 U) {
" Q) {6 h7 K# m //这里可以做任何你想做的事了,HOOK成功3 l: T6 X5 ~8 P6 W) u$ l
outputdebugstr("HOOK ExtTextOutA suscess!");
% f( D( z& P- s/ R5 F: } BOOL result = _ExtTextOutA(x, y, flags, lprect, str,count,lpDx);//调用原始函数( x4 U6 ~9 b# L$ J! j# Z
return(result);/ q9 @( h4 c3 b. V0 s# q# O+ F
}
# J% Z+ e' Y: y4 p, V1 K5 E$ s: @' t" k/ W L
注意,生成的代码需要用gcc/mingw来编译,
% [2 o6 [3 r9 n' t主要是因为其中使用了gcc宏扩展6 r3 [3 s" W5 D% W8 S9 j& K9 w! L9 Y
#define CALLING_CONVENTION WINAPI // default for Windows DLLs4 U/ N" A5 L8 r1 x9 r
#define PROXY_FUNCTION(FUNCTION_NAME) /* for the proxified functions not modified */ \\
! X2 u1 {+ U) z# e a5 P _. u void CALLING_CONVENTION FUNCTION_NAME(void): J/ @* p0 n7 Z; z
#define PROXY_FUNCTIONX(FUNCTION_NAME) \\
4 d `* E6 X" }$ m$ S( k7 \ static PROXY_FUNCTION(*_##FUNCTION_NAME) = NULL; \\- |! U& ?& e. g$ L6 h
PROXY_FUNCTION(FUNCTION_NAME) { \\
. H7 w& J2 X! q/ t1 J3 P( W2 m* Q POP_EBP __asm__("jmp *__"#FUNCTION_NAME); \\
- J: n/ a/ P, L* Y }. L# x0 T# o% ~# Z/ _
#define CALL_FUNCTION(FUNCTION_NAME) \\
5 r, V9 K1 { u' ]: B7 D static CALLING_CONVENTION FUNCTION_NAME##_(*_##FUNCTION_NAME) = NULL; \\2 f0 a) T( p" T0 E" c0 H
CALLING_CONVENTION FUNCTION_NAME##_(FUNCTION_NAME)
9 r9 h) ]7 [" K: ]* ^1 @#define CALL_FUNCTION2(FUNCTION_RET, FUNCTION_NAME, FUNCTION_ARGS ...) \\
( I5 ~* z$ Q: R/ J static CALLING_CONVENTION FUNCTION_RET (*_##FUNCTION_NAME)(FUNCTION_ARGS) = NULL; \\
: ?8 Y* l. o$ {' a CALLING_CONVENTION FUNCTION_RET FUNCTION_NAME(FUNCTION_ARGS)+ I+ Q! K1 }+ `3 c' Q8 S
8 B; |4 I1 ^. h. d
& |2 C1 R# b- U p" ?等我回头翻译到VC里4 |; q M6 f X7 x; b
待续 |