|
40鱼币
在使用OD分析扫雷这个程序的时候,分析到它的开局安放雷的位置,寻找雷的所在位置(内存中)使用的方式我没有看懂,希望大神们给我讲解一下,谢谢了
010036C7 |> /FF35 34530001 push dword ptr ds:[0x1005334] ; 这个是当前雷图的宽度
010036CD |. |E8 6E020000 call winmine.01003940 ; 计算随机数的过程
010036D2 |. |FF35 38530001 push dword ptr ds:[0x1005338] ; 这个是当前雷图的高度
010036D8 |. |8BF0 mov esi,eax
010036DA |. |46 inc esi
010036DB |. |E8 60020000 call winmine.01003940 ; 计算随机数的过程
010036E0 |. |40 inc eax
010036E1 |. |8BC8 mov ecx,eax
010036E3 |. |C1E1 05 shl ecx,0x5 ; ECX左移5位
010036E6 |. |F68431 405300>test byte ptr ds:[ecx+esi+0x1005340],0x80 ; 这里是判断是否已经是雷了
010036EE |.^ 75 D7 jnz Xwinmine.010036C7 ; 是的话就回去重新随机
010036F0 |. |C1E0 05 shl eax,0x5
010036F3 |. |8D8430 405300>lea eax,dword ptr ds:[eax+esi+0x1005340]
010036FA |. |8008 80 or byte ptr ds:[eax],0x80 ; 修改数据为是 雷(8f) 如果不是雷,之前是 0f
010036FD |. |FF0D 30530001 dec dword ptr ds:[0x1005330] ; 总剩余雷数减一(剩余多少雷没有安放)
01003703 |.^\75 C2 jnz Xwinmine.010036C7
以上是我分析出的反汇编代码,我看出来的都已经加了注释
那么,我想问的是ecx+esi+0x1005340或者说eax+esi+0x1005340是怎么定位的雷?没看懂这种定位方式。。。。
为何ECX、EAX要左移5位(乘以32)呢?
还请大神详细地讲解一下~~
|
最佳答案
查看完整内容
是否有雷,原先是采用 二维数组 [ecx,esi] 来表示,其中 esi 有32 个元素, 二维数组在 内存中的 存储 是 采用 线性方式,第一组存完,存第二组。
第 0组 元素 [0,esi] 可以表示为 [0*32+esi ]
第1组 元素 [1,esi] 可以表示为 [1*32+esi ]
............
在汇编中 需要将 二维数组 〔ecx,esi] 转换成 一维数组的。
数组 [ecx*32+esi+0x1005340]
实现如下:
先将 ecx *32, 再 [ecx+esi+0x1005340] 寻址。
...
|