首页
社区
课程
招聘
[原创]asm的魅力(二)
发表于: 2009-9-4 12:08 18442

[原创]asm的魅力(二)

2009-9-4 12:08
18442
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
那么->是个什么东西?(到现在我都不知道这叫个什么操作符,呼呼)为什么我们不写成这样的: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
asm中没有->这样的操作符,那怎么实现b->c.charme这样的访问呢?只好是像上面这样写了
结果显示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

当然我们也可以每个ch1 ch2初始化不同的值,含笑大哥提到了有两种方法:
接受键盘输入和预设初值为一个数组

方法一和C语言里的访问形式就很接近了,但是很多人这样写:
lea	 ebx, stMy

mov eax, [ebx].p.a

这样是不对的,,,[EBX]并不足以确定一个他属于什么样的结构,当然结构里的成员无从得知了。

不管怎么样吧!asm里使用结构对程序的组织和效率是很有帮助的。。

基本就总结到这里吧!希望对大家有帮助!!不要小看这些小小的知识,如果你真的认真的看到这里了,理解了,运用了,逆向算什么,破解算什么,只要你足够聪明,无非变通的组织思维的过程!!!

我也不是为了说大话,呼呼!!!!希望大家进步,大四了,每天一节课。写点东西。留个回忆吧!!

[课程]Android-CTF解题方法汇总!

收藏
免费 8
支持
分享
最新回复 (23)
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
2
asm的魅力怎么会是接近人类思维呢?高级语言干啥去了…
2009-9-4 12:32
0
雪    币: 636
活跃值: (174)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
3
汇编有时很直接,很方便。
有的时候,某些功能只有汇编能完成(比如改CR0,关中断,直接I/O,等等等等……)。但是说实话,不喜欢在不必要的情况下,故意使用汇编去“扭曲”程序。

btw,曾子曰:七月份的尾巴你是狮子座
2009-9-4 14:08
0
雪    币: 112
活跃值: (48)
能力值: ( LV9,RANK:320 )
在线值:
发帖
回帖
粉丝
4
比如for(;;){}这样的循环,是C语言结构化的表示,,asm完全按人的思维想:
cmp eax,0
jl aa
aa:
   输出‘eax<0’
输出‘eax>=0’
完全是正常的思维流程,,只要代码表示下就可以 了

所谓的masm的伪指令:
.if eax>0
   xxxx
.else
yyyy
.endif
实际上这些伪指令做的就是优化结构的工作,和C是一样的道理。
只是我们习惯了,知道了if else这样的结构了,就觉得这样方便,,实际上不是我们的思维流程
asm是最贴切的思维流程
2009-9-4 14:08
0
雪    币: 112
活跃值: (48)
能力值: ( LV9,RANK:320 )
在线值:
发帖
回帖
粉丝
5
可能你所的扭曲程序时指我发的第一篇,实际上第一篇的那个程序,我要表达的意思很多:堆栈,调用,指令替换,扭曲。。很多的意思,,这些要表达的东西放一起,可能会显得程序时在故意的扭曲,实际上没有那样的意思,所以我说那个程序别扭,但是得好好的看,会有收获的,,,你说的asm的应用时对的,,同感,,,
2009-9-4 14:11
0
雪    币: 247
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
恩。
强烈支持
2009-9-4 15:14
0
雪    币: 393
活跃值: (100)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
7
asm会了好处很多.至于再"深入"只不过是把asm当一个游戏玩而已.刚开始会觉得好玩有趣,最后玩熟了, 再去试试c/c++. 会觉得根本不是在写程序而是在"说话"
2009-9-4 15:58
0
雪    币: 393
活跃值: (100)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
8
再弱弱的说一句...= =! 楼主asm就两个月水平
2009-9-4 15:59
0
雪    币: 112
活跃值: (48)
能力值: ( LV9,RANK:320 )
在线值:
发帖
回帖
粉丝
9
呼呼,过奖了,哪里有两个月啊,,只有一礼拜,,一礼拜都没有,,我根本不会。。

而且我也弱弱的说一句,我也就偶尔抽不玩asm的时候用vb.net写写管理软件,,,至于你说的玩玩c++那些高级的东西,,我想我比你玩的早吧,,什么是高级语言,我想我用的也不比你差。。

呼呼,,您真谦虚
2009-9-5 00:36
0
雪    币: 210
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
凑热闹123456
2009-9-6 16:56
0
雪    币: 215
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
学习之中~~
2009-9-6 19:10
0
雪    币: 808
活跃值: (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
12
非常弱的问句:你是什么水平?
2009-9-6 21:55
0
雪    币: 243
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
支持一下,写文章很累的!
期待 asm的魅力(三)
2009-9-7 13:03
0
雪    币: 205
活跃值: (12)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
14
不错. 语言只是个工具.喜欢哪个就用哪个.
2009-9-18 18:34
0
雪    币: 351
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
surport!!
2009-10-2 10:16
0
雪    币: 522
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
16
真累 呼呼。
一星期就能拿来做文章了 厉害。呼呼 。
2009-10-6 08:07
0
雪    币: 112
活跃值: (48)
能力值: ( LV9,RANK:320 )
在线值:
发帖
回帖
粉丝
17
呼呼,,会说呼呼俩字的就是熟人喽,呼呼,,一星期达到这水平?呼呼,,你知道,,那是绝对不可能的,,呼呼
2009-10-6 11:04
0
雪    币: 200
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
深有感触,ASM就是业界的利刃!
2009-10-6 15:42
0
雪    币: 248
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
觉得楼主写得很不错啊。。。
2009-10-8 10:09
0
雪    币: 205
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
“顶 你”,期待A3
2009-11-8 06:38
0
雪    币: 133
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
我也喜欢asm~
2009-11-15 10:14
0
雪    币: 656
活跃值: (448)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
22
mov eax,(M ptr [ebx]).p.a;; 居然还能这么用..学习了
2010-8-20 16:33
0
雪    币: 437
活跃值: (110)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
23
继续磨剑。。。。。。。。
2011-3-14 00:53
0
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
觉得有问题...
asm中没有->这样的操作符,那怎么实现b->c.charme这样的访问呢?只好是像上面这样写了
结果显示p2.cc.charme的值是0,意图来看应该是显示20h。
错误在哪里?
OD调试看看,可以很清楚的看到,内存空间中:
P1.charme--------------------------0400xxxxh
Charme1
P2.cc.charme----------------------0400yyyyh
根本就是两个变量,怎么可能访问到呢,,照这样看来我们这样修改下:
mov ebx, p2.cc.charme+4,就输出20h,但实际上这只是投机,只是跳过了charme1的空间,访问了下p1.charme,一点也不能通用。

本身你实例化的时候p1, 和p2就没有半毛钱关系吧...你在实例化aa结构的时候里面在实例化bb结构..也就是那个cc.....然后你通过对aa结构中的cc赋值...然后想从实例化的p1中拿出来...
他们本身就应该是两个对象吧....
并不会因为你
p2 bb <>  ;;;;;;;注意
p1 aa <>  ;;;;;;;;注意
这样声明..那么p1和p2中的cc是同一个内存区域...在逻辑上他们也应该是独立的啊....
2011-8-30 10:01
0
游客
登录 | 注册 方可回帖
返回
//