<2003/3/20>
背单词背的无聊,前几天跑xdict的词库,跑了一些就删了,今天来提取"新东方背单词II"的词库。网上的词库很多了,很久以前在一个palm的论坛上,一个高人说要弄一个朗文的背单词词库,期待了很久,还是没出来,估计是工作太忙了......
工具如下 win32dasm,vc.net
其实一切破解的过程就是浪费时间的过程~~,然后就是观察,猜测,当然人聪明,花的时候也少:-)
用win32dasm打开Recite.exe,新东方背单词II就这一个文件,连dll都没有,真是......
打开之后,跳转到书籍管理~~
这词库无论如何都要ReadFile吧,就在ReadFile的地方设了几个断点,具体点就是在dasm'函数'->import出来的地方找到ReadFile, (KERNEL32.ReadFile),然后double click几下,用F2设几个断点,然后跟踪了一下,发现在 书籍管理中切换书籍的时候,有很多地方被循环调用,最常见的就是40be3b处一系列代码 [e, ei, 4] [4n, 1n] [4'b1nd4n] [4'baid] [4'biliti] ['eib4l] 这显然就是词库了, 音标.... 想想就知道这个软件每次都是把所有单词读入内存,好了,让我们看看00407610处的函数的参数 lea ecx,dword ptr [esp+2C] 好了,剩下的就是在这个地方,加入自己代码,打开一个文件,在后面写入0x400长,然后flushbuf,close掉 自己写汇编是不是很麻烦?不用啊,我们的.net出场了 OFSTRUCT ofs; 然后在vc.net中直接看汇编代码 sub esp,0A8h (以上代码略有修改)这段代码最开始sub esp,0A8h ,用0A8h的空间来保存 显然,为了避免麻烦,还要在前面 然后就是找个地方把我们的代码放起来了~,翻啊翻,翻到最后4e20e9的地方,找了一大片空地,好了,就是这儿了 在Recite.406e3b地方,把原来的mov ecx,dword ptr [esp + 450]改为 然后在4e20e9的地方写原来的那个mov,接着写自己的代码,就是上面的汇编代码 好了搞定了,每次在书籍管理中切换词库之前,先del c:/c,然后建一个空的文件名叫c,切换完后c就被写完了,除了所有的正常内容外,后面会多一点内容,删掉就可以了(因为我们每次都是写的400,没有检查返回)
其中有一个函数调用最关键
call Recite.00407610
这个函数调用之后,堆栈里面出现0x400长的一段数据
如下
<0>
<1>
<2>forsake, desert, relinquish
<3>
<4>
<5>
mov esi,eax
push ecx
lea edx,dword ptr [esp+40]
push esi
push edx
看看再想想就知道esp+40是第一个参数,是个buf地址,esi当时是0x400,应该就是buf长,剩下的一个如果没弄错,应该是操作对象。函数调用如果没记错,应该是__cdecl,从右向左入栈,被调者自己清栈.
char name[8];//为了方便‘看’,定义为8
name[0] = 'c';
name[1] = ':';
name[2] = '//';
name[3] = 'c';
name[4] = 0 ;
HANDLE handle = (HANDLE)OpenFile(name,&ofs,OF_WRITE);
SetFilePointer(handle,0,0,FILE_END);
char buf[0x10];
DWORD byte;
WriteFile(handle,buf,0x10,&byte,0);
FlushFileBuffers(handle);
CloseHandle(handle);
mov al,63h
mov byte ptr [esp+8],al
mov byte ptr [esp+0B],al
push 1
lea eax,[esp+24]
push eax
lea ecx,[esp+10]
push ecx
mov byte ptr [esp+15],3A
mov byte ptr [esp+16],5C
mov byte ptr [esp+18],0
call dword ptr [__imp__OpenFile@12 (405010h)]
//004e3238
push 2
push 0
mov esi,eax
push 0
push esi
call dword ptr [__imp__SetFilePointer@16 (40500Ch)]
//004e32c0
push 0
lea edx,[esp+8]
push edx
push 400 //写入字节数
lea eax,[esp+1Ch] //写入地址
push eax
push esi
call dword ptr [__imp__WriteFile@20 (405008h)]
//004e32b8
push esi
call dword ptr [__imp__FlushFileBuffers@4 (405004h)]
//004e32bc
push esi
call dword ptr [__imp__CloseHandle@4 (405000h)]
//004e32ac
add esp,0A8
OFSTRUCT ofs;
char name[8];
之类的变量,最后add esp,0A8还原
push esi
push edx
push ecx
push eax
在后面
pop eax
pop ecx
pop edx
pop esi
jmp 4e20e9
nop
nop
两个nop是为了填空
其中的函数调用OpenFile,SetFilePointer等要替换成相应的地址
如何找到地址?无非就是在'函数'->import出来了地方double click几下,然后copy一下了咯
比如 SetFilePointer就是
call [004e32c0]
而且其中FileWrite的buf地址要改一下,
lea eax, dword ptr [esp+0000010C]
最后要jmp回原地,继续执行
c就是相应的词库,然后可以干吗呢?好像新东方背单词II词库也不比网上流传的词库好多少......