dllproxyskel使用起来比较简单,dllproxyskel自动从你输入的原始DLL中提取所有导出函数符号
' Q( k# G' J/ a! ^7 i然后按一定的格式生成.c文件,自动将所有的dll函数信息记录进.def, 做好替换 函数在.c,5 y3 H0 g& D3 \- O; w* @
通过在.c文件中#ifdef DLL_PATH 来寻找原始DLL路径(默认为\\system32),原始DLL里的函数调用是原函数名前面加个下划线_
$ I9 t* B. h! m0 W! M% h9 [9 [+ u比如Exttextout,在.c里做完自己的事后可以调用 _Exttextout 来完全其原本的工作
) _9 A5 U- d, q1 c1 r- ~+ P& c+ n C5 j
命令行输入& n* j' C1 V) Q$ u, |7 Z
dllproxyskel.exe <input.dll>
& J3 ]2 U7 @9 @$ I9 W- open file D:\\项目\\dllproxyskel\\input.dll2 a- d, C* v- i4 D5 Z$ @. J
1 D2 k1 x# A1 Q9 B+ ^5 I
3 ~- P0 Q; }3 q+ K! U$ |% z w------------------------------------------------------------------' T# _& k* M0 E2 s8 ^" z
我们需要额外添加的代码1 F' q+ G! B/ V6 G# F9 |
#define _WINGDI_ //这个值从wingdi.h里获取,仅仅在代理系统DLL的时候需要9 F- G9 x, z" O8 \- J0 T9 E! d
//定义了两种声明代理函数的宏,CALL_FUNCTION与CALL_FUNCTION2" x& P9 D9 t& K
//这里我采用第二种,将返回值与函数名与参数列表一起作为宏内容,下面第一个参数BOOL 是ExtTextOutA的返回值; Z6 a8 v7 O) h2 p5 `
CALL_FUNCTION2(BOOL, ExtTextOutA,) I3 D$ E$ l: n. m/ v0 f
HDC hdc,
9 \3 P1 w- ?7 h9 d& [4 _' a% L INT x,
# Y. N: I4 f* ~. g INT y,# o/ |# ?& m2 f/ I1 L
UINT flags,3 q5 ?, M6 B. y0 @) C3 T0 ]% u
const RECT* lprect,
" D) e$ L ?+ Q* X LPCSTR str,. v; e' {" b( k# c+ M
UINT count,
" O) ?4 C+ {; Z: L- y" P const INT* lpDx" ?1 z) J; G8 b8 N* j
) {
8 j4 W% H8 w( \ //这里可以做任何你想做的事了,HOOK成功1 {8 k+ q9 i- ?3 L3 T) K2 d
outputdebugstr("HOOK ExtTextOutA suscess!");
) n; F, g2 O- t' h' b BOOL result = _ExtTextOutA(x, y, flags, lprect, str,count,lpDx);//调用原始函数/ T6 Q& G3 ^) x' ~
return(result);
# |. x& p; E ^, w; z0 U}/ i# T8 Z$ d7 D( M6 M
# i% B& _" ~' ]5 Y; Y
注意,生成的代码需要用gcc/mingw来编译,
& Z W7 {6 q; j# K! o3 |主要是因为其中使用了gcc宏扩展2 [) p. m( _2 X
#define CALLING_CONVENTION WINAPI // default for Windows DLLs+ b# k" ]( R" e- I( j2 A( ?
#define PROXY_FUNCTION(FUNCTION_NAME) /* for the proxified functions not modified */ \\
. i* v) J' y& m1 M void CALLING_CONVENTION FUNCTION_NAME(void)
% [0 y' z* }" `5 ?9 @9 i6 g#define PROXY_FUNCTIONX(FUNCTION_NAME) \\5 v" Q- {4 l1 d
static PROXY_FUNCTION(*_##FUNCTION_NAME) = NULL; \\
1 h" y$ {9 J+ @7 U0 W* S PROXY_FUNCTION(FUNCTION_NAME) { \\5 Z5 r2 } \# w+ j$ E
POP_EBP __asm__("jmp *__"#FUNCTION_NAME); \\/ i$ w( `& e0 g8 X
}
( I) F2 D$ D* A, v! v#define CALL_FUNCTION(FUNCTION_NAME) \\
w, S8 O0 M1 V7 i4 b; @# } R/ ? static CALLING_CONVENTION FUNCTION_NAME##_(*_##FUNCTION_NAME) = NULL; \\7 n* n' `1 k" _6 l0 y Y$ [
CALLING_CONVENTION FUNCTION_NAME##_(FUNCTION_NAME)- \2 R+ }( a0 e1 I! ?7 u
#define CALL_FUNCTION2(FUNCTION_RET, FUNCTION_NAME, FUNCTION_ARGS ...) \\4 J1 n1 ~, F9 E) g" R% }0 b* n
static CALLING_CONVENTION FUNCTION_RET (*_##FUNCTION_NAME)(FUNCTION_ARGS) = NULL; \\
8 k4 {1 _/ o) u CALLING_CONVENTION FUNCTION_RET FUNCTION_NAME(FUNCTION_ARGS)5 K6 `& M' f# B+ f
9 D" j0 ]) J4 q9 O+ t8 H* {/ D: L9 T& [4 d: G) I/ f- N
等我回头翻译到VC里
! W% L3 W6 R4 v& }( ^待续 |