Asm的魅力(二)
Author:charme
Data:2009.9.4
Index:hi.baidu.com/charme000
废话:
上一篇大牛牛们都说是出力不讨好,呼呼!我还是一贯作风吧:一笑而过。
做个简单的类比:
开发黑客软件的人笑只会使用软件入侵的菜菜肤浅,如果认可这个挂点的话,那研究asm本身实质的人就应该嘲笑利用asm搞逆向和破解的人了。
而实际上这是几个不同的领域,所以没有什么吃力不讨好的说法。
会写软件的人必然懂得入侵的原理,所以懂asm的人逆向只是个时间问题。
曾子曰:自作孽,不可活!
如果为了凑篇精华,拼凑代码科普出来,基本等于没有创造!!!我不干那样的事情!!
还是相信女王大牛的教诲:这个世界永远注重的是创造。
正文:
程序语言中的结构体是常见的访问内存中存储数据的一种方式,有点不必说了,大家接触过结构的都明白。那么asm中的结构用的当然也比较多。
结构可以嵌套,但是初学者必然的会有一些迷惑。
(一)明白结构访问的本质
首先看一个C语言中的结构使用:
代码:
Struct A { Int charme; }*a; Struct B { A c; }*b
那么->是个什么东西?(到现在我都不知道这叫个什么操作符,呼呼)为什么我们不写成这样的:b.c.charme?不就是访问成员嘛!!!到这里就是重点了,->操作符的本质是什么?
再看一段程序:
代码:
int _ClientLogin( LPVOID _lpStruct) { TranSocket *stSock; ... int k = stSock->dwIndex; //相当于取stSock.dwIndex 赋值给k ... return (0); }
看完这个我们可能就明白了,stSock只是一个指针,指向TranSocket结构的一个指针。这样做只是为TranSocket结构预留了一个空间,方便以后的初始化。
这就是->的本质!!!!!!!!!!!!!!!!!!这个必须搞清楚的,搞清楚了这个才能理解怎么嵌套。
(二)asm中的结构嵌套的错误
那么就之前的那个结构嵌套。很多人可能会这样写(我之前也是这么写的,呼呼):
代码:
.386 .model flat,stdcall option casemap:none include windows.inc include kernel32.inc include user32.inc includelib user32.lib includelib kernel32.lib aa struct charme dd ? aa ends bb struct charme1 dd ? cc aa <> bb ends .data? p2 bb <> ;;;;;;;注意 p1 aa <> ;;;;;;;;注意 szEAX db 8 dup('0'),0 strr1 dd ? .data strr db "charme",0 .code ExchangCode proc w32BitCode:DWORD,lpCode:DWORD push ebx push ecx push esi mov esi,lpCode mov eax,w32BitCode mov ecx,8 @@nextchar: push ecx rol eax,4 mov ebx,eax and ebx,0000000Fh cmp bl,09 jle @@char0_9 add bl,07h @@char0_9: add bl,30h mov BYTE PTR [esi],bl inc esi pop ecx loop @@nextchar pop esi pop ecx pop ebx ret ExchangCode endp main proc mov p1.charme,20h mov ebx, p2.cc.charme push offset szEAX push ebx call ExchangCode push 40h push offset strr push offset szEAX push 0 call MessageBox ;push 03e8h ;call Sleep push 0 call ExitProcess main endp end main
结果显示p2.cc.charme的值是0,意图来看应该是显示20h。
错误在哪里?
OD调试看看,可以很清楚的看到,内存空间中:
P1.charme--------------------------0400xxxxh
Charme1
P2.cc.charme----------------------0400yyyyh
根本就是两个变量,怎么可能访问到呢,,照这样看来我们这样修改下:
mov ebx, p2.cc.charme+4,就输出20h,但实际上这只是投机,只是跳过了charme1的空间,访问了下p1.charme,一点也不能通用。
(三)重写asm结构嵌套
之所以出现上面的错误,实际上还是因为没有真正的理解了结构访问成员的本质。Asm的魅力在于最大限度的接近人的思维,所以他很灵活,但是灵活的话就需要你掌握本质。否则灵活的旁边就是混乱。(我也搞不清楚这俩词到底有啥区别,呼呼)
那么在来看看
代码:
.386 .model flat,stdcall option casemap:none include D:\MASMPlus\Include\windows.inc include D:\MASMPlus\Include\kernel32.inc include D:\MASMPlus\Include\user32.inc includelib D:\MASMPlus\Lib\kernel32.lib includelib D:\MASMPlus\Lib\user32.lib X struct a dd 10h b db 10 dup(?) X ends Y struct cc dd ? d dd ? e db ? Y ends M struct p X <> q Y <> M ends .data stMy M <> szEAX db 8 dup('0'),0 szTitle db "charme",0 .code ExchangCode proc w32BitCode:DWORD,lpCode:DWORD push ebx push ecx push esi mov esi,lpCode mov eax,w32BitCode mov ecx,8 @@nextchar: push ecx rol eax,4 mov ebx,eax and ebx,0000000Fh cmp bl,09 jle @@char0_9 add bl,07h @@char0_9: add bl,30h mov BYTE PTR [esi],bl inc esi pop ecx loop @@nextchar pop esi pop ecx pop ebx ret ExchangCode endp start: ;;正确做法一 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;lea ebx, stMy ;;指向M结构的一个指针 ;mov eax,(M ptr [ebx]).p.a;;必须加上M ptr因为C里面我们也看到了,实际上这个指向M结构的指针已idngyao确定是某个结构的,,因为你lea ebx, stMy只是初始化了一个指针,并没有给你要初始化的结构分配空间 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;正确在做法二 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;mov ebx,sizeof M ;;mov eax,stMy[ebx].p.a ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;正确做法三 lea esi,stMy.p mov ebx,(X ptr [esi]).a push offset szEAX push ebx call ExchangCode push 40h push offset szTitle push offset szEAX push 0 call MessageBox ret end start
看看方法一和方法三,你可以对比出一个规律来:就是我们确定了指针,一定要明确他是要初始化一个什么样的结构。
方法二是可扩展的。
比如有一个叫做AA的结构,先假设他有两个成员
我们定义一个结构数组:aa AA 3 dup(<0,0>)
那么我们可以循环赋值,下面给一个示例:
代码:
AA struct Ch1 dd ? Ch2 dd ? AA ends .data Align word aa AA 3 dup(<0,0>) .code Start: Mov edi,0 Mov ecx,3 Mov eax,1 Loopp: Mov (AA ptr aa[edi]).ch1,eax Mov (AA ptr aa[edi]).ch2,eax Add edi,TYPE AA ;;或者是SIZEOF AA,这里获得的大小就是结构数组里单个数组的大小 Inc eax Loop loopp Push 0 Call ExitProcess End start
接受键盘输入和预设初值为一个数组
方法一和C语言里的访问形式就很接近了,但是很多人这样写:
代码:
lea ebx, stMy mov eax, [ebx].p.a
不管怎么样吧!asm里使用结构对程序的组织和效率是很有帮助的。。
基本就总结到这里吧!希望对大家有帮助!!不要小看这些小小的知识,如果你真的认真的看到这里了,理解了,运用了,逆向算什么,破解算什么,只要你足够聪明,无非变通的组织思维的过程!!!
我也不是为了说大话,呼呼!!!!希望大家进步,大四了,每天一节课。写点东西。留个回忆吧!!