运行后:
本机机器码"195F9059606EEB4723128A216ED1426B”,在内存中搜索该字符串,可以得到3个地方,我这里以最后搜索到的地方为切入点,
为什么? 找到的3个地方都下内存断点判断,刚好最后找到的那个注册码最早生成而已,以哪个作为切入点都是一样的。
快速判断:
软件重新RUN,不断d 00EECF68,等该内存段分配完毕后,在该地址下内存断点,第一次断在: 复制代码
是写0的操作,估计是初始化。
第二次断点: 复制代码
发现此时[00EECF68]内存段正在写入数据。断点设在00F05A94处,等机器码全部写完后PATCH之,
取消断点,RUN,第一次时生成.KEY文件,再重复上次过程则跳过注册框正常运行。
在做INLINE HOOK程序时,发现几个问题:
1,机器码放置的位置是变化的,比如说这次是[00EECF68],那下次有可能是[00EFCF68]。再跟踪几次,发现还好,虽然地址在变化,但在该内存段的OFFSET值是固定的。V2.1.0DEMO版本的OFFSET值为01CF68:
2,机器码所在的区段是固定的,即总是在SIZE = 0008A000 的段中。 复制代码
在此基础上,考虑HOOK VrtualAlloc,
1,根据Alloc的内存SIZE定位到机器码所在的段,从而获得段地址。
2,段地址 + 机器码OFFSET值(比如这里的:00ED0000 + 01CF68)即为机器码的位置。
3,看能否找到某个API,在刚机器码刚生成时HOOK住,然后直接PATCH 机器码即可。
以上1,2点不用测试即可知道能实现,第3点的API在测试多遍后都没能找到合适的API,只好放弃,因为程序有可能在生成机器码后进行运算直接与注册码进行比较或与注册码进行运算后进行解码,也就是说这个过程可能不用调用到API。
那么换个思路,我们从前面的内存写入断点可以定位到生成最终机器码的过程代码:
经过几次测试,发现改代码的OFFSET值也是固定的,固定值为35A92 :
因此思路可以调整如下:
1,根据Alloc的内存SIZE定位到机器码所在的段,从而获得段地址。
2,段地址 + CODE OFFSET值(比如这里的:00ED0000 + 035A92 )即为生成机器码代码的地址。
3,HOOK 生成机器码的代码:
原来的:
很明显,中间一段代码为无用代码,更改为类似如下代码(其中00F597D1为任选的一段空白代码处):
再来做00F597D1处的PATCH代码:
把代码写入程序后发现运行时出错,很明显,有类似CRC校验的东西存在。 还好经过测试后发现;
1,机器码只要PATCH一次后即可。
2,校验只校验部分代码,比如刚刚那空白处00F597D1写入的代码即不在校验范围内。
那么,我们只要在PATCH机器码后把原始的CODE写回即可。
如果不符合以上两个条件,那么只能通过多次HOOK API经过多次更改代码来BYPASS了(兵无定势,根据实际情况分析,哪种可行就选哪种了)。
本机机器码"195F9059606EEB4723128A216ED1426B”,在内存中搜索该字符串,可以得到3个地方,我这里以最后搜索到的地方为切入点,
为什么? 找到的3个地方都下内存断点判断,刚好最后找到的那个注册码最早生成而已,以哪个作为切入点都是一样的。
快速判断:
软件重新RUN,不断d 00EECF68,等该内存段分配完毕后,在该地址下内存断点,第一次断在:
- 00EF7BB3 8915 84CFEE00 mov dword ptr [EECF84], edx
- 00EF7BB9 E9 D2360000 jmp 00EFB290
第二次断点:
- 00F05A92 8802 mov byte ptr [edx], al
- 00F05A94 C3 retn
取消断点,RUN,第一次时生成.KEY文件,再重复上次过程则跳过注册框正常运行。
在做INLINE HOOK程序时,发现几个问题:
1,机器码放置的位置是变化的,比如说这次是[00EECF68],那下次有可能是[00EFCF68]。再跟踪几次,发现还好,虽然地址在变化,但在该内存段的OFFSET值是固定的。V2.1.0DEMO版本的OFFSET值为01CF68:
2,机器码所在的区段是固定的,即总是在SIZE = 0008A000 的段中。
- Memory map, 条目 51
- 地址=00ED0000
- 大小=0008A000 (565248.)
- 属主= 00ED0000 (自身)
- 区段=
- 类型=Priv 00021040
- 访问=RWE
- 初始访问=RWE
1,根据Alloc的内存SIZE定位到机器码所在的段,从而获得段地址。
2,段地址 + 机器码OFFSET值(比如这里的:00ED0000 + 01CF68)即为机器码的位置。
3,看能否找到某个API,在刚机器码刚生成时HOOK住,然后直接PATCH 机器码即可。
以上1,2点不用测试即可知道能实现,第3点的API在测试多遍后都没能找到合适的API,只好放弃,因为程序有可能在生成机器码后进行运算直接与注册码进行比较或与注册码进行运算后进行解码,也就是说这个过程可能不用调用到API。
那么换个思路,我们从前面的内存写入断点可以定位到生成最终机器码的过程代码:
- 00F05A92 8802 mov byte ptr [edx], al
- 00F05A94 C3 retn
- $+35A92 > 8802 mov byte ptr [edx], al
- $+35A94 > C3 retn
1,根据Alloc的内存SIZE定位到机器码所在的段,从而获得段地址。
2,段地址 + CODE OFFSET值(比如这里的:00ED0000 + 035A92 )即为生成机器码代码的地址。
3,HOOK 生成机器码的代码:
原来的:
- 00F05A85 F7D5 not ebp
- 00F05A87 53 push ebx
- 00F05A88 66:8BD2 mov dx, dx
- 00F05A8B 5B pop ebx
- 00F05A8C F7D5 not ebp
- 00F05A8E 66:57 push di
- 00F05A90 66:5F pop di
- 00F05A92 8802 mov byte ptr [edx], al
- 00F05A85 /E9 473D0500 jmp 00F597D1
- 00F05A8A |90 nop
- 00F05A8B |90 nop
- 00F05A8C |90 nop
- 00F05A8D |90 nop
- 00F05A8E |90 nop
- 00F05A8F |90 nop
- 00F05A90 |90 nop
- 00F05A91 |90 nop
- 00F597D1 81FA 87CF5801 cmp edx, 158CF87
- 00F597D7 74 05 je short 00F597DE
- 00F597D9 ^ E9 B4C2FAFF jmp 00F05A92
- 00F597DE 83EA 1F sub edx, 1F
- 00F597E1 C702 30463043 mov dword ptr [edx], HWID1
- 00F597E7 C742 04 3342443>mov dword ptr [edx+4], HWID2
- 00F597EE C742 08 4231333>mov dword ptr [edx+8], HWID3
- 00F597F5 C742 0C 4241443>mov dword ptr [edx+C], HWID4
- 00F597FC C742 10 3043313>mov dword ptr [edx+10], HWID5
- 00F59803 C742 14 4343344>mov dword ptr [edx+14], HWID6
- 00F5980A C742 18 4646303>mov dword ptr [edx+18], HWID7
- 00F59811 C742 1C 4141414>mov dword ptr [edx+1C], HWID8
- 00F59818 ^ E9 75C2FAFF jmp 00F05A92
1,机器码只要PATCH一次后即可。
2,校验只校验部分代码,比如刚刚那空白处00F597D1写入的代码即不在校验范围内。
那么,我们只要在PATCH机器码后把原始的CODE写回即可。
如果不符合以上两个条件,那么只能通过多次HOOK API经过多次更改代码来BYPASS了(兵无定势,根据实际情况分析,哪种可行就选哪种了)。