调试环境:WinXP SP2 QQ2006 Beta2
调试工具:OnlyDBG
测试步骤:
1.进入QQ目录下,改名或者删除npkcrypt.sys文件。运行QQ,出现QQ键盘保护启动失败,先关了QQ。
2.运行OnlyDBG,打开LoginCtrl.dll。右键,然后查找,然后点当前模块中的名称(标签)。
3.找到npkcntc.#1导入函数,只要选择第一个就行了。然后按回车键,点弹出窗口里的,再回车。代码如下:
CODE:[Copy to clipboard]60A3F9A8 . 8BCE mov ecx, esi
60A3F9AA . E8 49050000 call 60A3FEF8 //检测npkcrypt.sys文件是否存在
60A3F9AF . 85C0 test eax, eax
60A3F9B1 74 0C je short 60A3F9BF //关健点,改为jne,意思是npkcrypt.sys文件不存在的时跳转
60A3F9B3 . |FF15 E466A460 call [<&npkcntc.#1>]
60A3F9B9 . |8986 90010000 mov [esi+190], eax
60A3F9BF > \39BE 90010000 cmp [esi+190], edi
60A3F9C5 . 0F8E 88000000 jle 60A3FA53
60A3F9CB . |68 9E0B0000 push 0B9E //0B9E资源为显示鍵盘加密成功的字符。
60A3F9D0 . |8D8E 94010000 lea ecx, [esi+194]
60A3F9D6 . |E8 5D1A0000 call <jmp.&MFC42.#4160>
60A3F9DB . |E8 BE1A0000 call <jmp.&MFC42.#1168>
60A3F9E0 . |8B40 0C mov eax, [eax+C]
60A3F9E3 . |57 push edi
60A3F9E4 . |6A 0C push 0C
60A3F9E6 . |6A 0C push 0C
60A3F9E8 . |6A 01 push 1
60A3F9EA . |68 C13E0000 push 3EC1 //注意这里的3EC1,加密正确显示的资源名,非常重要
60A3F9EF . |50 push eax
60A3F9F0 . |FF15 7C66A460 call [<&USER32.LoadImageA>]
60A3F9F6 . |8D7E 64 lea edi, [esi+64] //健盘加密技术启运成功显示的图像
60A3F9F9 . |6A 00 push 0
60A3F9FB . |8BCF mov ecx, edi
60A3F9FD . |8986 88010000 mov [esi+188], eax
60A3FA03 . |E8 11FAFFFF call 60A3F419
60A3FA08 . |FF15 F066A460 call [<&npkcntc.#9>]
60A3FA0E . |85C0 test eax, eax
60A3FA10 . |75 08 jnz short 60A3FA1A
60A3FA12 . |6A 01 push 1
60A3FA14 . |FF15 E066A460 call [<&npkcntc.#4>]
60A3FA1A > |85FF test edi, edi
60A3FA1C . |75 04 jnz short 60A3FA22
60A3FA1E . |33C0 xor eax, eax
60A3FA20 . |EB 03 jmp short 60A3FA25
60A3FA22 > |8B47 20 mov eax, [edi+20]
60A3FA25 > |68 46080000 push 846
60A3FA2A . |50 push eax
60A3FA2B . |FFB6 90010000 push dword ptr [esi+190]
60A3FA31 . |FF15 EC66A460 call [<&npkcntc.#5>]
60A3FA37 . |85FF test edi, edi
60A3FA39 . |75 04 jnz short 60A3FA3F
60A3FA3B . |33C0 xor eax, eax
60A3FA3D . |EB 03 jmp short 60A3FA42
60A3FA3F > |8B47 20 mov eax, [edi+20]
60A3FA42 > |6A 02 push 2
60A3FA44 . |50 push eax
60A3FA45 . |FFB6 90010000 push dword ptr [esi+190]
60A3FA4B . |FF15 E866A460 call [<&npkcntc.#10>]
60A3FA51 . |EB 43 jmp short 60A3FA96
60A3FA53 > \FF15 9460A460 call [<&KERNEL32.GetLastError>] //npkcrypt.sys文件不存在,跳到这里
60A3FA59 . E8 401A0000 call <jmp.&MFC42.#1168>
60A3FA5E . 8B40 0C mov eax, [eax+C]
60A3FA61 . 57 push edi
60A3FA62 . 6A 0C push 0C
60A3FA64 . 6A 0C push 0C
60A3FA66 . 6A 01 push 1
60A3FA68 . 68 C23E0000 push 3EC2 // 改 注意这里是3ec2,错误的资源名,改成正确的资源名为3ec1
60A3FA6D . 50 push eax
60A3FA6E . FF15 7C66A460 call [<&USER32.LoadImageA>]
60A3FA74 . 8D7E 64 lea edi, [esi+64]
60A3FA77 . 6A 01 push 1
60A3FA79 . 8BCF mov ecx, edi
60A3FA7B . 8986 88010000 mov [esi+188], eax
60A3FA81 . E8 93F9FFFF call 60A3F419
60A3FA86 . 68 9F0B0000 push 0B9F //改 这里是0B9F,显示健盘加密失败的字符资源,前面为0b9e,改成0b9e
60A3FA8B . 8D8E 94010000 lea ecx, [esi+194]
60A3FA91 . E8 A2190000 call <jmp.&MFC42.#4160>
60A3FA96 > E8 031A0000 call <jmp.&MFC42.#1168>
60A3FA9B . 8B40 0C mov eax, [eax+C]
60A3FA9E . 6A 00 push 0
60A3FAA0 . 6A 10 push 10
60A3FAA2 . 6A 10 push 10
60A3FAA4 . 6A 01 push 1
60A3FAA6 . 68 C33E0000 push 3EC3
60A3FAAB . 50 push eax
60A3FAAC . FF15 7C66A460 call [<&USER32.LoadImageA>]
格式不好弄,大家凑合着看吧
有了上面的偏移量以及数据后,现在我们来用程序实现,这里给出C修改LoginCtrl.dll的源码:
CODE:[Copy to clipboard]#include <stdio.h>
#include <stdlib.h>
int main()
{
char modification[1];
FILE *f = fopen("E:\\QQ\\LoginCtrl.dll", "rb+"); //打开QQ目录下的LoginCtrl.dll文件
fseek(f, 63921, SEEK_SET); //定位文件指针到63921(\xf9b1)
modification[0] = 115;
fwrite(modification, sizeof(char), 1, f); //修改为115(\x75)
//下面的道理相同,具体的offset请参看上面调试时候的数据
fseek(f, 64105, SEEK_SET);
modification[0] = 193;
fwrite(modification, sizeof(char), 1, f);
fseek(f, 64135, SEEK_SET);
modification[0] = 158;
fwrite(modification, sizeof(char), 1, f);
fclose(f);
return 0;
}
好了,用C,短短的几行代码就搞定了^^
好累,睡觉去咯。。。。
呼呼~~~~