好友
阅读权限 40
听众
最后登录 1970-1-1
本文适合还没有入门的新朋友上手用的,所以,各位大牛就可以飘过不看它了!
游戏的服务器列表更新了,而存服务器信息的XML在游戏的更新服务器上加密保存的,没能力分析它的解密算法,就想写个程序,从内存里读出来,工作量就是那么多,不如索性做成教程,分享给像我一样刚刚入门的朋友,说不定就又能混一篇精华,哈哈……
其实真的不知道该给这个破烂起个什么名字了,怎么看怎么感觉在教人做外挂¥%#¥%
不多废话,进入主题,我现在要找服务器列表,当然就要先从内存里搜一个服务器的名字(别的信息不知道,只能搜名字了!)
在 OD 里的数据区中看一下这几个地址,确定,第一个地址也就是: 01329F6C
就是我们像要的地址了,至于为什么,你看一下就可以知道了(因为第一个在一个结构体数组里,其他的都是独立的,所以第一个是!)。
好了,在 OD 里,来到 01329F 6C 这个地址,在第一个 DWORD 上下内存访问断点:
来到这里:
现在我们需要知道的是, EAX的内容是从哪里来的,所以向上看: 0040CA3B |> \8BC2 |mov eax, edx ; 1
是EDX给的EAX,再向上:0040CA17 |. 8B83 18010000 |mov eax, dword ptr [ebx+118]
0040CA1D |. 8B34A8 |mov esi, dword ptr [eax+ebp*4]
0040CA20 |. 8D04A8 |lea eax, dword ptr [eax+ebp*4]
0040CA23 |. 8D57 04 |lea edx, dword ptr [edi+4] ; 1
0040CA26 |. 85D2 |test edx, edx
0040CA28 |. C746 3C 01000> |mov dword ptr [esi+3C], 1
0040CA2F |. 8D9E 8C000000 |lea ebx, dword ptr [esi+8C]
0040CA35 |. 75 04 |jnz short 0040CA3B
这个流程应该是比较简单的,我就从头分析一下:0040C8C0 /$ 6A FF push -1
0040C8C2 |. 68 08184600 push 00461808 ; 咐|g; SE 处理程序安装
0040C8C7 |. 64:A1 0000000>mov eax, dword ptr fs:[0]
0040C8CD |. 50 push eax
0040C8CE |. 64:8925 00000>mov dword ptr fs:[0], esp
0040C8D5 |. 83EC 24 sub esp, 24
0040C8D8 |. 53 push ebx
0040C8D9 |. 8BD9 mov ebx, ecx
0040C8DB |. 8B83 78010000 mov eax, dword ptr [ebx+178] ; 取出返回值,如果是-1就不做处理!
0040C8E1 |. 83F8 FF cmp eax, -1
0040C8E4 |. 895C24 08 mov dword ptr [esp+8], ebx
0040C8E8 |. 0F84 89000000 je 0040C977
0040C8EE |. 55 push ebp
0040C8EF |. 57 push edi
0040C8F0 |. 8D4C24 2C lea ecx, dword ptr [esp+2C]
0040C8F4 |. 51 push ecx
0040C8F5 |. 8D5424 2C lea edx, dword ptr [esp+2C]
0040C8F9 |. 52 push edx
0040C8FA |. 50 push eax
0040C8FB |. 8D8B 58010000 lea ecx, dword ptr [ebx+158]
0040C901 |. E8 0ACAFFFF call 00409310
0040C906 |. 33ED xor ebp, ebp
0040C908 |. 3BC5 cmp eax, ebp ; 如果函数返回值是0,就走人~~~
0040C90A |. 74 69 je short 0040C975
0040C90C |. 8B78 04 mov edi, dword ptr [eax+4]
0040C90F |. 3BFD cmp edi, ebp
0040C911 |. 74 62 je short 0040C975
0040C913 |. 56 push esi ; ESI和EBX的值都是004812A8
0040C914 |. 8BB3 DC000000 mov esi, dword ptr [ebx+DC]
跟进ESI看下:
[code]011A21E8 0D F0 AD BA 70 5C 32 01 58 7D 32 01 2C 7F 32 01 .瓠簆\2 X}2 ,2
011A21F8 0D F0 AD BA 88 31 32 01 A8 31 32 01 A8 31 32 01 .瓠簣12 ?2 ?2
011A2208 0D F0 AD BA 28 01 30 01 42 01 30 01 42 01 30 01 .瓠? 0 B 0 B 0
011A2218 0D F0 AD BA 28 23 1A 01 00 00 00 00 0D F0 AD BA .瓠?# .....瓠
011A2228 80 23 1A 01 00 00 00 00 00 F0 AD BA 0D F0 AD BA
继续:0040C91A |. 8B46 04 mov eax, dword ptr [esi+4] ; 取出了各个大区的序号•~~
0040C91D |. 3BC5 cmp eax, ebp
到这里可以知道,大区的地址指针+偏移的形式应该在:[004812A8+DC]+4]
看下EAX的内容:01325C70 01 00 00 00 B9 E3 B6 AB C7 F8 00 00 58 F8 17 04 ...广东区..X?
01325C80 00 00 00 00 58 F8 17 04 EA 76 94 7C 00 00 1A 01 ....X? 陃攟..
01325C90 64 77 94 7C D0 31 30 01 00 00 1A 01 D8 31 30 01 dw攟?0 .. ?0
01325CA0 00 00 00 00 64 77 94 7C 50 32 30 01 00 00 1A 01 ....dw攟P20 ..
01325CB0 98 83 1A 01 C0 30 30 01 00 00 1A 01 00 00 00 00 槂 ?0 .. ....
01325CC0 06 00 00 00 B0 4E 31 01 0F 00 00 00 A8 4E 31 01 ...癗1 ...∟1
01325CD0 A8 4E 31 01 30 18 00 00 78 01 1A 01 28 03 1A 01 ∟1 0 ..x (
01325CE0 01 00 00 00 40 05 1A 01 38 00 00 00 48 32 30 01 ...@ 8...H20
01325CF0 78 01 1A 01 30 2E 38 32 30 34 2E 30 36 00 00 00 x 0.8204.06...
这个就是服务器大区的大概的结构了,里面各个数据的含义还不是很清楚,不过不用着急,通过代码,我们都会弄明白的!
继续回到代码中分析:0040C91F |. C74424 1C FFF> mov dword ptr [esp+1C], -1
0040C927 |. 75 04 jnz short 0040C92D
0040C929 |. 33C0 xor eax, eax
0040C92B |. EB 18 jmp short 0040C945
0040C92D |> 8B4E 08 mov ecx, dword ptr [esi+8]
看一下ECX的内容吧:0132D048 0D F0 AD BA 0D F0 AD BA 0D F0 AD BA 0D F0 AD BA .瓠?瓠?瓠?瓠
0132D058 0D F0 AD BA 0D F0 AD BA 0D F0 AD BA 0D F0 AD BA .瓠?瓠?瓠?瓠
0132D068 0D F0 AD BA 0D F0 AD BA 0D F0 AD BA 0D F0 AD BA .瓠?瓠?瓠?瓠
0132D078 0D F0 AD BA 0D F0 AD BA 0D F0 AD BA 0D F0 AD BA .瓠?瓠?瓠?瓠
都是同一个数字,暂且不多考虑,估计接下来应该是遍历大区的信息啊,想下,我们在写程序的时候,循环需要什么来着,对,就是循环多少次啊,接下来的代码就是计算有多少个大区,以控制循环多少次了!0040C930 |. 2BC8 sub ecx, eax
0040C932 |. B8 8DC0088C mov eax, 8C08C08D
0040C937 |. F7E9 imul ecx
0040C939 |. 03D1 add edx, ecx
0040C93B |. C1FA 08 sar edx, 8
0040C93E |. 8BC2 mov eax, edx
0040C940 |. C1E8 1F shr eax, 1F
0040C943 |. 03C2 add eax, edx ;这里就是大区的数量了OD显示的是0x12,即有0x12个大区
好了,到这里,EAX里存的就是有多少个大区了
继续看0040C945 |> 33C9 xor ecx, ecx
0040C947 |. 3BC5 cmp eax, ebp
0040C949 |. 76 29 jbe short 0040C974
0040C94B |. 8B97 84000000 mov edx, dword ptr [edi+84] ; 取出我们选择的大区的序号
0040C951 |. 8B76 04 mov esi, dword ptr [esi+4] ; 取出大区的首个元素:序号
下面开始循环,遍历各个大区,我们取大区的信息也主要就依靠这个循环了~~~0040C954 |. 33FF xor edi, edi
0040C956 |. 897424 24 mov dword ptr [esp+24], esi
0040C95A |. 897C24 10 mov dword ptr [esp+10], edi
0040C95E |. 8BFF mov edi, edi
0040C960 |> 391437 / cmp dword ptr [edi+esi], edx ; 循环比较,看看取那个区下的服务器
0040C963 |. 74 26 |je short 0040C98B ; 只要是我们选的区,拿就跳走,不是就继续循环
0040C965 |. 41 | inc ecx
0040C966 |. 81C7 D4010000 | add edi, 1D4 ; 在内存里,每个大区信息的结构体大小为0x1D4
0040C96C |. 3BC8 | cmp ecx, eax
0040C96E |.^ 72 F0 \ jb short 0040C960
0040C970 |. 897C24 10 mov dword ptr [esp+10], edi
根据这个循环,我们可以很轻松的写出遍历所有大区的代码了,不过不用太着急,在这里标记一下,因为,这个大区的结构中很多的数据成员,我们都不清楚,现在只知道第一个成员是大区的ID,第二个是名字,而且结构的大小要凑够0x1D4,其他的都还未知,继续分析,或许等下就清晰了,嘿嘿!
继续看代码:0040C98B |> \8B8437 C80100> mov eax, dword ptr [edi+esi+1C8] ; 看到了吧,大区数构中偏移第1C8的成员是个最小值
0040C992 |. 3BC5 cmp eax, ebp
0040C994 |. 897C24 10 mov dword ptr [esp+10], edi
0040C998 |. 75 06 jnz short 0040C9A0
0040C99A |. 896C24 20 mov dword ptr [esp+20], ebp
0040C99E |. EB 1E jmp short 0040C9BE
0040C9A0 |> 8B8C37 CC0100> mov ecx, dword ptr [edi+esi+1CC] ; 大区数构中偏移第1CC的成员是个最大值
0040C9A7 |. 2BC8 sub ecx, eax ; 同算大区的数量一样,计算服务器的数量
0040C9A9 |. B8 E1830F3E mov eax, 3E0F83E1
0040C9AE |. F7E9 imul ecx ; 3E0F83E1*(最大值-最小值)
0040C9B0 |. C1FA 06 sar edx, 6 ; 取其积的高32位值右移6位
0040C9B3 |. 8BC2 mov eax, edx
0040C9B5 |. C1E8 1F shr eax, 1F ; 再移动0x1F位
0040C9B8 |. 03C2 add eax, edx ; 取他们的和OD显示是4,即4个服务器,循环4次
0040C9BA |. 894424 20 mov dword ptr [esp+20], eax ; 把结果保存一下
哈哈,结构越来越清晰,思路越来越明确,大家猜下,接下来是要干什么了啊~~~~0040C9BE |> \8B83 1C010000 mov eax, dword ptr [ebx+11C] ; 还不清楚它的作用,OD显示是6,先不管它
0040C9C4 |. 33D2 xor edx, edx
0040C9C6 |. 85C0 test eax, eax
0040C9C8 |. 894424 18 mov dword ptr [esp+18], eax
0040C9CC |. 0F8E 95010000 jle 0040CB67
0040C9D2 |. 33C9 xor ecx, ecx
0040C9D4 |. EB 0A jmp short 0040C9E0 ; 下面的代码应该很眼熟吧,典型的For循环
0040C9D6 |> 8B4C24 2C /mov ecx, dword ptr [esp+2C]
0040C9DA |. 8B5424 28 |mov edx, dword ptr [esp+28]
0040C9DE |. 8BFF |mov edi, edi
0040C9E0 |> 3B5424 20 cmp edx, dword ptr [esp+20] ; 将计数器EDX跟服务器的数量进行比较,看看循环是否结束
0040C9E4 |. 0F83 42010000 |jnb 0040CB2C
0040C9EA |. 8B8437 C80100>|mov eax, dword ptr [edi+esi+1C8] ; 取出第一个服务器的信息结构的首地址
[ 本帖最后由 bester 于 2009-2-17 13:07 编辑 ]
免费评分
查看全部评分