易语言实地培训长期招生 QQ1615457736

乐易论坛

 找回密码
 立即注册

微信登录

微信扫码,快速开始

QQ登录

用QQ账号登陆

导航
导航
培训
培训
产品
产品
易歪歪客服聊天助手——永久免费程序员熬夜必备神器阿里云服务器最高¥1888云产品通用代金券我要租广告
易歪歪客服聊天助手——永久免费全新E3,E5机器远程出租阿里云服务器低至10元/月我要租广告
易歪歪客服聊天助手——永久免费阿里云虚拟机主机 低至350元/1年 最高2000云产品通用代金券我要租广告
TQApiEc---专为PCQQ/TIM 开发的API接口模块,让你直接调用内部功能TQApiEc---专为PCQQ/TIM 开发的API接口模块,让你直接调用内部功能TQApiEc---专为PCQQ/TIM 开发的API接口模块,让你直接调用内部功能TQApiEc---专为PCQQ/TIM 开发的API接口模块,让你直接调用内部功能
WxApiEc-专为PCWx开发的API接口模块,让你快速调用内部功能WxApiEc-专为PCWx开发的API接口模块,让你快速调用内部功能WxApiEc-专为PCWx开发的API接口模块,让你快速调用内部功能WxApiEc-专为PCWx开发的API接口模块,让你快速调用内部功能
查看: 10610|回复: 13
收起左侧

[纯源码] 通过APIHook实现反远程注入及钩子检测

[复制链接]
  • TA的每日心情
    无聊
    前天 02:37
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2017-9-20 20:18:36 | 显示全部楼层 |阅读模式

    乐易编程网免费注册!抓住机会哦!

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    写在最前:
    3 Y4 O, v3 f( ]6 a3 I( I6 c: v这只是一份demo.朋友软件被通过注入的方式做了PJ,我就帮忙写了这份源码3 n" w7 i$ K" G& X" c2 I
    实际上这只是一种治标不治本的方法,但是也有一定的可行性) r+ a3 v! X3 T2 n4 v0 W
    就这种方法而言,我的这份demo并非完善,甚至还有很多很显而易见的漏洞6 P0 z1 P5 d6 b6 O1 t
    比如我没HOOK LoadLibraryEx,也没有hook 使用宽字符的函数,不过原理基本没啥变化,有心人可以自行完善和补充.5 w, G% C+ u' W0 Y8 p6 X
    % r9 A: s& P. F1 s
    工作原理:0 i+ l* B! o/ @  d  H" r
    1.通过hook LoadLibrary拦截所加载的模块.
    9 Z& k* H, W" D9 p  Nb.在LoadLibrary中插入自己的暗桩代码.同时自己再调用LoadLibrary,根据暗桩是否触发判断hook是否被恢复, L% U* s) J5 I- @
    c.通过模块路径,模块版权信息,数字签名判断模块是否为非法模块
    5 p/ k% ~6 i* `
    ) [* y: X, x& ^4 g3 Y9 Q代码说明:( A& Y5 m& |3 q9 D
    如下是对LoadLibraryA Hook的代码$ e$ s+ F1 N2 O3 q; ?
    把LoadLibrary返回的hModule保存起来,并且插入了我们自己的暗桩代码,如果是调用我们自己的验证模块,则调用模块内的check函数) s& c0 `% G, K  T# \* U% C
    同时还用一个定时器调用LoadLibrary.以确保check函数被一直调用$ o4 M! R8 m, f
    [ecode=1].版本 20 A, @. _; ]7 _  P
    .支持库 const0 c) t2 N9 w4 ]+ A1 z
    .支持库 spec
    . C/ v) |# n6 J; [, o- ?& w" s2 u' c) n9 {8 P
    .子程序 hookLoadlibraryA, 整数型
    % m8 o; n. {5 |1 e) z.局部变量 loadlibraryAddr, 整数型
      \! W; a/ y2 g( y, F& i1 a.局部变量 oldFlag, 整数型
    0 c9 E. Z) P# F- `. m% B% [+ {.局部变量 byte, 字节集
    / g$ I; K! m9 v.局部变量 lenth, 整数型
    5 ?+ v3 B' p% d0 }% g.局部变量 myJmp, 整数型
    + D$ G2 c. }, l* d* S; o% Z4 q9 ]9 W& h$ h1 j  g
    loadlibraryAddr = _取API地址 (“kernel32.dll”, “LoadLibraryA”)
    4 D# L0 ^' m! C  g9 [8 q% R.如果真 (loadlibraryAddr = -1)
    8 S+ o2 z0 \4 M1 v. z$ O8 [: t- X    返回 (-1)$ S- z) a7 M1 |9 O, \
    .如果真结束
    3 ^' M/ y  D4 ~9 E: X2 FmyJmp = _取子程序真实地址 (&_LoadlibraryA) + 4* C  ~) X) W: t" ~% ~4 V
    VirtualProtect (myJmp, 4, #PAGE_EXECUTE_READWRITE, oldFlag)
    / b9 @( W& t  J/ p% a4 W写到内存 (到整数 (loadlibraryAddr + 5), myJmp, )" ^$ q6 G) L$ M; m6 ~) G' p. p9 t
    VirtualProtect (myJmp, 4, oldFlag, oldFlag)4 L- A2 n" C' S" L2 E$ w
    ) M  b, I8 s1 |1 `3 y! o' s+ v
    lenth = 到整数 (&myLoadlibraryA) - loadlibraryAddr - 5
    0 x6 K8 r) n) qbyte = { 233 } + 到字节集 (lenth)( C. O& F6 Y$ {2 Y1 v
    VirtualProtect (loadlibraryAddr, 5, #PAGE_EXECUTE_READWRITE, oldFlag)
    , x1 A! e' G0 z7 o- g: m2 K/ w) {写到内存 (byte, loadlibraryAddr, )& V4 Z. ]3 c) i4 I; f- T9 u) J
    VirtualProtect (loadlibraryAddr, 5, oldFlag, oldFlag)
    ! y7 i/ b: p: D/ V" k! |: U  o返回 (loadlibraryAddr)% _$ N* `# b8 `+ p3 J
    ) P# [+ f& J, Q4 s
    .子程序 _LoadlibraryA, 整数型
    1 \% d( V: T/ q/ o6 g8 z/ Z.参数 lpLibFileName, 整数型
    ! h; ?4 \% R' k" U. T4 a1 }7 U/ z" k3 m+ N2 j
    ' _asm:mov eax,0x400000# s9 J8 V* ]; H* z. f
    ' _asm:jmp eax
    ) Y- s3 {+ }, o& G返回 (0)
    * z" q6 c3 _5 L1 ?
    4 f5 V# U4 X0 W- Y; J8 L4 W5 N. \: j.子程序 myLoadlibraryA, 整数型3 {- {) R1 ~* R  t9 `" H. t! G- W
    .参数 lpLibFileName, 整数型  X% d- a* W* v9 I
    .局部变量 hModule, 整数型7 d* @: l% m. N2 U+ W
    .局部变量 fileName, 文本型( c) b, z; q! Q; A8 J; k  `

    ; C: ^8 @# H3 J' v: a6 XhModule = _LoadlibraryA (lpLibFileName)
    * u) R& b5 U! f.如果真 (hModule > 0)
    $ h3 o5 K) p. V1 B    fileName = 到文本 (_读字节集 (lpLibFileName, 200)), w. s) H1 h' j2 w
        .判断开始 (-1 ≠ 寻找文本 (fileName, keyDll, , 真))6 J, |8 r% X6 }* z6 t8 N
            调用子程序 (GetProcAddress (hModule, “check”), , , )' `) c* T: w: M+ v, m) i
        .判断 (-1 = 寻找文本 (fileName, “fne”, , 真))
    # z8 h. w1 L6 E( C# L2 S1 V        loaded.add (fileName)
    + R$ Q/ e- L8 [8 A    .默认* b  F: V. w6 w

    . D( j6 z/ O( P3 L8 U4 [( X4 K3 U3 ?    .判断结束
    $ ]& ?! K: {& V$ `8 e+ Y- x8 `8 K. t5 i& N" G. p  w
    .如果真结束
    ! V# l* A* b! P返回 (hModule)7 s, \. k) h- V' j3 O& E
    [/ecode]" T! W# n& A. {
    8 a- J, J( f4 o4 a! s: h, M+ L7 h
    check函数:( [5 C! Y2 i' J* W
    check函数取得MessageBoxW函数的地址,并且修改头4字节的内存为timeGettime(), |( ?8 M$ \0 ~  _1 Z2 J
    因为易语言用的都是ascii,所以MessageBoxW一般很少用到% x1 [. F* y+ ]1 t) E1 A
    当然后期的修改也可以对timegettime的值做加密再写入或者用pipedName等其他办法代替,还可以甚至加上你的心跳包
    , C. w- u+ t* s; _" C[ecode=1].版本 24 j- x& ^" ~* b# h1 f1 A9 L

    - i) G% m0 M0 o5 P- u! F.子程序 check, , 公开
    / p# U. k% W' b( {! {  I.局部变量 hModule, 整数型8 {% _& E' d$ h
    .局部变量 address, 整数型
    5 |0 I6 G0 ~+ M0 Y.局部变量 oldFlag, 整数型$ o- u5 w" Q/ K) @2 Z

    ! A" d/ ^0 s) ~9 ihModule = LoadLibrary (“user32.dll”)
    ! Y% C. @8 d! T. jaddress = GetProcAddress (hModule, “MessageBoxW”)* q( G5 I; ^) Y) {
    VirtualProtect (address, 4, #PAGE_EXECUTE_READWRITE, oldFlag)
    , I# o1 [+ @0 C4 E$ d) V4 U写到内存 (timeGetTime (), address, )
    - r5 A& Y8 Z0 M1 n0 x, l% ?* aVirtualProtect (address, 4, oldFlag, oldFlag); Q' E) v, z7 J- g5 X
    [/ecode]
      |2 N! ?$ U- |; [6 O9 {) |+ w! g2 k# N
    钩子检查:
    , D4 |1 ]( R  B, d2 V取出我们写入的时间值,和timeGetTime做比对,看看是否超过一定的范围,是的话则说明钩子被处理8 V7 }; ^  g: i  q: }4 D3 [
    [ecode=1].版本 2
    0 A8 U. [0 c6 \8 [- m) [.支持库 const, ?5 x% m5 P6 j/ g

    , N( ]- D0 n+ Q.子程序 _按钮2_被单击
    7 `$ |$ E! I+ M/ F4 |) L8 n.局部变量 hModule, 整数型
    & s- v$ z& V( R, N/ a% e.局部变量 address, 整数型8 d  P6 I& R; s6 Z) V$ w
    .局部变量 oldFlag, 整数型
    5 o: [, ~5 c) ]: E+ q8 }& G1 K.局部变量 integer, 整数型
    0 v' f0 }! Y1 z1 F2 B# M
    5 y2 w4 T/ f6 G# n: A! q+ fhModule = LoadLibrary (“user32.dll”)" H6 I9 M* u, ]! U% E) _1 p
    address = GetProcAddress (hModule, “MessageBoxW”)
    ! |$ O1 b) ?7 J0 e5 O& XVirtualProtect (address, 4, #PAGE_EXECUTE_READWRITE, oldFlag)
    ! Q$ u$ `! B6 ^% j8 B" Y" r& ointeger = _读整数型 (address): N7 n5 B4 e( J$ m
    VirtualProtect (address, 4, oldFlag, oldFlag)
    3 c. d4 B: ~# i1 u2 N.判断开始 (取绝对值 (timeGetTime () - integer) > 1000)
    # z, \& C9 l" l+ N. t+ Q    编辑框1.加入文本 (“程序异常” + #换行符)
    / t' y; d* P* d! z3 j9 \.默认
    . R6 n3 I/ ?) K9 C8 B    编辑框1.加入文本 (“检测通过” + #换行符)
    . p# u/ h" w! _) [" d[/ecode]
    - k6 v0 }2 S+ n
    # L# c6 W" C, t6 l4 t模块检查
    8 }# I: ]: A! l- L0 P9 ~a.首先我们判断是否有非白名单内的模块在根目录下加载,是的话判定为非法模块.这种办法可以预防一些挟持注入.当然可能这样写有点不合理2 b/ z; L4 Y8 `1 r8 H" @+ p9 I
    b.判断文件的版权信息,如果是白名单版权的则认定为有效文件
    , ]: g+ P, C9 A& @9 _c.判定数字签名是否有效.% q- a0 c( |: T$ ^
    [ecode=1].版本 24 Q6 v2 D* ~; _7 {
    .支持库 eAPI
    ' q% ^  p) @1 Q7 T9 w. R* v& H/ R# X; A
    .子程序 模块检查
    ) C$ Y7 m2 A7 w( R6 l.局部变量 i, 整数型
    , C" h/ N6 m9 h/ ].局部变量 hModule, 整数型0 c6 N. y# E7 y3 Q
    .局部变量 fileFullName, 文本型- o9 g  P% b7 Q& }
    .局部变量 filePath, 文本型% O' \) R% s* b2 I+ b8 D$ ^
    .局部变量 info, 文件版本信息
      a' v& [2 L6 J% ?8 }6 ?. m0 O- \) J: G* U+ E  ^2 b* W5 N
    .计次循环首 (loaded.size (), i)
    2 Y& U7 |6 c* g, r6 l) L6 I2 x  ^8 `    hModule = GetModuleHandle (loaded.get (i)): X7 q6 z$ ?+ `6 R. U8 V* y
        .判断开始 (hModule = 0)6 M, I4 v9 t8 f) L" G5 e
            编辑框1.加入文本 (loaded.get (i) + “.hModule=NULL” + #换行符)
    - Q) P, p4 f; N5 S8 v    .默认) P  C# m' \7 S% C2 G% j. ]4 i. I
            fileFullName = getModulePath (hModule)
    ; z7 C; u. g6 e1 \4 C        .判断开始 (fileFullName = “”)7 t% y8 ?, V2 N7 l
                编辑框1.加入文本 (loaded.get (i) + “.hModule=” + 到文本 (hModule) + “ getPath=NULL” + #换行符)
    ' o& Z& t' h# @5 f        .默认2 a; e4 ]* f% Y: v/ `
                filePath = _全路径取路径 (fileFullName)
    / r1 [" F/ d0 l1 v/ s7 a0 ?$ H            .判断开始 (-1 ≠ 寻找文本 (取运行目录 (), filePath, , 真))
    ; I# b$ i) d* Y+ h$ u1 t0 A                .判断开始 (whiteList.index (loaded.get (i)) = 0)
    % k# E4 _# v% G# L/ m                    编辑框1.加入文本 (loaded.get (i) + “.hModule=” + 到文本 (hModule) + “ hackerModule” + #换行符)
    ) o8 k8 S6 w: u4 ]9 D7 M  d% z+ \- M                .默认. u: `& O0 Z$ I0 _+ j( g/ e
                        编辑框1.加入文本 (loaded.get (i) + “.hModule=” + 到文本 (hModule) + “ whiteListModule” + #换行符)
    " X  |, ], [* U) l2 Z/ {2 `$ l                .判断结束
    5 @0 V' N2 d0 A3 f$ F6 W9 S. {8 P. k4 \
                .默认
    1 z5 ]% B& W* l% m! ]                取文件版本信息 (fileFullName, info)
    4 ?, }( K5 h" A5 Z7 G0 Z  V6 H* m                .判断开始 (-1 ≠ 寻找文本 (info.合法版权, “Microsoft Corporation. All rights reserved”, , 真))0 q. _2 K: |$ x* X
                        编辑框1.加入文本 (loaded.get (i) + “.hModule=” + 到文本 (hModule) + “ Microsoft Corporation Library” + #换行符)
    ' [3 O% z# K6 n6 g                .判断 (VerifyEmbeddedSignature (A2W (fileFullName)))
    * M- ?% K4 N: w  T& [+ k                    编辑框1.加入文本 (loaded.get (i) + “.hModule=” + 到文本 (hModule) + “ userModule” + #换行符)
    9 d; e4 x, C3 Q, L. @                .默认
    8 R) J  y+ S) }                    编辑框1.加入文本 (loaded.get (i) + “.hModule=” + 到文本 (hModule) + “ hackerModule” + #换行符)2 \+ b  K" V( C, {( `
                    .判断结束+ b+ X; u! ^( L3 h, r* ~

    4 b8 M/ \2 V% a  u8 R            .判断结束
    ) Y; W  t: L2 |$ N
    % L" w4 \2 k) R        .判断结束
    + C4 Y0 @' m7 E6 f, M$ e
      `- H) h- l. Z. o* t    .判断结束
    # N/ j# |, M% b+ o$ b8 C
    1 G/ B2 ]" j% o! ~0 {0 s.计次循环尾 ()
    , w0 v5 m# H2 f2 [4 Q" D[/ecode]
    , M5 V' {4 e6 X$ }& H' @6 o9 N
    - K, j) b3 k) d1 Q3 c; K写在最后:( Z, u1 J, M% l( w8 P# ?
    本人搞了几年游戏了,也多少了解到一些PJ与反PJ,个人观点还是认为没必要太崇拜壳子
    6 U$ q/ {8 P3 x+ K+ B1 b基本把关键代码VM一下也差不多了,壳子更多的是调试和一些相关的检测,这些其实网上很多资料了.- r' L1 Q% g7 X
    起码我这一两年来,我的验证系统都只用vmp1.22做了vm,没有任何其他的壳子的保护.
    * [( y8 B/ d2 H- E0 d( Y主要的还是自己的系统是否严谨,是否能有效的增加PJ的难度." I& J, z' `  G$ S- o- P
    如果一个市面上销售的软件,个人更倾向于一个全局钩子,对一些敏感的api做处理,自身把用到的一些敏感的api自己做一个hook做处理,加上CRC可能效果未必比壳差
    ) o4 `1 I% \) E1 f6 w) e当然了,以上都是本人的愚见而已,希望大神们也不吝赐教.
    ' s/ V+ @. g0 j
    易语言实地培训,报名联系QQ 1615457736
    [超强]《易语言软件加密(防破解)技术特训》
    回复

    使用道具 举报

  • TA的每日心情
    无聊
    2018-2-16 15:02
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2018-2-21 04:24:00 | 显示全部楼层
    谢谢分享            
    易语言实地培训,报名联系QQ 1615457736
    [超强]《易语言软件加密(防破解)技术特训》
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    前天 02:37
  • 签到天数: 15 天

    [LV.4]偶尔看看III

     楼主| 发表于 2017-9-20 20:20:04 | 显示全部楼层
    补充下附件:2 s9 e) G7 }3 S3 N7 a
    exe.e (22.1 KB, 下载次数: 41)
    易语言实地培训,报名联系QQ 1615457736
    [超强]《易语言软件加密(防破解)技术特训》
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2020-3-23 07:01
  • 签到天数: 49 天

    [LV.5]常住居民I

    发表于 2017-9-23 02:52:07 | 显示全部楼层
    论坛 附件  下载的大小是39B
    易语言实地培训,报名联系QQ 1615457736
    [超强]《易语言软件加密(防破解)技术特训》
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2020-3-23 07:01
  • 签到天数: 49 天

    [LV.5]常住居民I

    发表于 2017-9-20 20:53:42 | 显示全部楼层
    远程汇编   也可以的

    点评

    是的,所以说这个方法绕过的办法太多了,所以也提到了全局钩子做HOOK  发表于 2017-9-20 23:18
    易语言实地培训,报名联系QQ 1615457736
    [超强]《易语言软件加密(防破解)技术特训》
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    2018-11-13 20:12
  • 签到天数: 32 天

    [LV.5]常住居民I

    发表于 2017-9-20 21:49:34 | 显示全部楼层
    不明觉厉!!!
    易语言实地培训,报名联系QQ 1615457736
    [超强]《易语言软件加密(防破解)技术特训》
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2019-3-14 11:25
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2017-12-22 09:33:11 | 显示全部楼层
    666666,学习了!
    易语言实地培训,报名联系QQ 1615457736
    [超强]《易语言软件加密(防破解)技术特训》
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2018-1-25 16:00:10 | 显示全部楼层
    感谢分享,学习学习
    易语言实地培训,报名联系QQ 1615457736
    [超强]《易语言软件加密(防破解)技术特训》
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2018-1-28 18:48:51 | 显示全部楼层
    感谢分享!下来学习学习!
    易语言实地培训,报名联系QQ 1615457736
    [超强]《易语言软件加密(防破解)技术特训》
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2019-1-21 03:44:23 | 显示全部楼层
    谢谢分享     
    易语言实地培训,报名联系QQ 1615457736
    [超强]《易语言软件加密(防破解)技术特训》
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    关闭

    乐易推荐上一条 /6 下一条

    QQ|网站地图|Archiver|手机版|小黑屋|乐易论坛 ( 湘ICP备19007035号-2 )

    GMT+8, 2020-4-5 14:56 , Processed in 0.136538 second(s), 121 queries .

    Powered by Discuz! X3.4 Licensed

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表