首页
社区
课程
招聘
汇编代码长度问题
发表于: 2009-12-24 10:18 4262

汇编代码长度问题

2009-12-24 10:18
4262
我在汇编代码中 如此定义:
CodeStart equ this byte
pop eax
invoke _GetFileAlignSize,CodeLength                                                
mov [edi].SizeOfRawData,eax                                                         
mov eax,ImageSectionHead.PointerToRawData                                          
add eax,ImageSectionHead.SizeOfRawData                                             
mov [edi].PointerToRawData,eax                                                      
mov dwWritePointer1,eax                                                            
mov [edi].Characteristics,0e0000020h                                                                                                              
assume esi:nothing,edi:nothing                                                      
                                                                                    
invoke UnmapViewOfFile,hHandle                                                      
invoke CloseHandle,hMap                                                            
invoke CloseHandle,hFile                                                            
mov hFile,NULL                                                                     
mov hMap,NULL                                                                       
mov hHandle,NULL                                                                    
                                                                                    
invoke CreateFile,offset szFileName,GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ,\
                                                                NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL                       
mov hFile,eax                                                                                                                            
invoke SetFilePointer,hFile,dwWritePointer1,0,FILE_BEGIN                                                                                                    
invoke _GetFileAlignSize,CodeLength                                                
push ecx                                                                                       
invoke WriteFile,hFile,CodeStart,eax ,esp,NULL
CodeEnd     equ this byte
CodeLength = CodeEnd - CodeStart
nop

但此段源代码经过编译链接后最终的二进制代码长度 并不是  CodeLength值,明显比     CodeLength小.

这是为什么

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (11)
雪    币: 75
活跃值: (803)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
2
没有人碰到过?我用的是masm32
2009-12-24 21:55
0
雪    币: 444
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
我用的也是MASM32(严格限制的MASM32,楼主这种代码编译通不过)。
对于这个问题我用过3种方法。
方法一:
lea eax, offset CodeEnd
lea ebx, offset  CodeStart
sub ebx,eax
mov CodeLength,ebx

方法二:
程序开始处  CodeStart   DD   0    ;也可以把这个标记为代码的起始处,这个更符合楼主的情况,见后面说明。
程序末尾处  CodeEnd     DD   0    ;也可以把这个标记为代码的末尾处,这个更符合楼主的情况。
定义一个变量    CodeLengthADDR   DD    CodeEnd-CodeStart
mov CodeLength , dword ptr[CodeLengthADDR]

说明下,即为:
CodeStart equ this byte
pop eax

改写为  CodeStart: pop  eax

方法三:
程序CodeStart处有  call    CodeEnd
CodeEnd:  pop  eax
           mov  ebx, dword ptr[eax-4]   
           mov CodeLength ,ebx
           jmp   eax

注意:如果CodeEnd和CodeStart之间间距小于0FFh,请使用类似以下代码

程序CodeStart处有  call    CodeEnd
CodeEnd:  pop  eax
           mov  bl, byte ptr[eax-1]   
           mov  CodeLength ,bl       ;如果这里操作数出错,请你先把bl扩展为ebx(指令我忘记了)
           jmp   eax

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
推荐第二种方法。以上几种方法改变了寄存器的值,楼主需不需要保存该寄存器的值,自己改下哈。

说实话,都一天了,楼主都没有想出以上任意一种方法吗?汗一个。
2009-12-24 22:58
0
雪    币: 75
活跃值: (803)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
多谢楼上,不过我更倾向于找到出现这问题的原因,:)程序早已完工
2009-12-25 17:56
0
雪    币: 444
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
据我猜测,问题出在
编译器如何解释CodeStart equ this byte和CodeEnd     equ this byte
以上2个属于宏汇编,建议用OD看下这里会变成什么汇编代码
还有CodeLength = CodeEnd - CodeStart这样的代码那个等于号是相当于直接赋值语句?

另,楼主
CodeEnd equ this byte
CodeLength = CodeEnd - CodeStart

两行代码之间添加一个 DB 0 看看, 不知道是不是标识的问题。

楼主用OD把编译后的汇编执行代码列出来看看,毕竟大家直接做你这个的比较少。
2009-12-25 18:56
0
雪    币: 75
活跃值: (803)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
6
我自己重新试了一下,
CodeStart equ this byte
               xxxx
               xxxx
               .....
               xxxx
CodeEnd equ this byte
CodeLength = CodeEnd - CodeStart
这种写法 在大多数情况下 codelength得到的值是正确的,
但我碰到的情况好像是个例外,不正确.

大家可是试试我的程序,看看哪里出了问题,

               .data?                                             
Buffer        db 1024 dup (?)                                                                             
               .const                                             
szTxt       db '%d',0                                                                                 
                .code                                             
include         code.asm                                          
start:                                                      
                invoke wsprintf,offset Buffer,offset szTxt,CodeLength
                invoke MessageBox,NULL,offset Buffer,NULL,MB_OK      
                invoke ExitProcess,NULL                              
               end start                                            

code.asm内容形式如下:
CodeStart equ this byte
       xxxxx
       .....
CodeEnd equ this byte
CodeLength = CodeEnd - CodeStart

code.asm经汇编生成代码如下:
00401000   .  90            nop
00401001   ?  90            nop
00401002   ?  0000          add     byte ptr [eax], al
00401004   ?  0000          add     byte ptr [eax], al
00401006   ?  0000          add     byte ptr [eax], al
00401008   ?  0000          add     byte ptr [eax], al

...........................
省略若干

0040167C  |.  1040 00       adc     byte ptr [eax], al
0040167F  |?  59            pop     ecx
00401680  |?  90            nop
00401681  |?  90            nop
00401682  |.  90            nop
00401683  |.  90            nop

00401684 >|.  68 CD070000   push    7CD
00401689  |?  68 14204000   push    00402014                         ;  ASCII "%d"
0040168E  |?  68 00304000   push    00403000
00401693  |?  E8 20000000   call    <jmp.&user32.wsprintfA>

由此可见 实际生成的代码量 为 683H 1667byte

但MessageBox弹出的值却是1997 byte,莫非让我碰到了一个masm32编译器的一个bug?

附源代码
上传的附件:
2009-12-25 22:57
0
雪    币: 444
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
1997 byte 即地址00401685处的DWORD值000007CD的十进制数值。

由此可见 实际生成的代码量 为 683H 1667byte
。你已经说了,代码量为683h.

但是为什么实际值是7CD呢。因为楼主的CodeStart equ this byte和CodeEnd equ this byte编译器认为不在同一个区块。如果不是这个原因,请看下面在同一个区块的情况:

楼主定义那一群_PeekNamedPipe              dd                ?和szWSAStartup         db  'WSAStartup',0 这种东西编译到哪里去了。如果楼主这段汇编代码起始入口在CodeStart equ this byte处的话,就是楼主所说的683h。但是显然,楼主不是这样的,那么楼主那一大群定义就被你算漏了;但是编译器是按编译时的相对位置计算的,所以它计算进了那一大群定义的大小。

所以,是汇编代码起始入口处和CodeStart标记不一致的原因。

如果楼主那一大群定义在内存中的存储位置不在401000与00401683之间,那么说明就是这个原因,楼主你验证下哈。

楼下的说法,我感觉哈,应该是没影响的。我使用过和楼主很类似的汇编代码,能得到准确值的。
2009-12-26 00:42
0
雪    币: 257
活跃值: (28)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
8
CodeEnd equ this byte
CodeLength = CodeEnd - CodeStart
两句的顺序
2009-12-26 00:50
0
雪    币: 75
活跃值: (803)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
9
"如果楼主那一大群定义在内存中的存储位置不在401000与00401683之间,那么说明就是这个原因,楼主你验证下哈。"
都在里面的,
如果不在里面,我后面重定位后都无法取得对应的数据的,code.asm里面的程序代码是跑不起来的
2009-12-26 02:57
0
雪    币: 444
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
那无奈了,只能看下宏汇编代码,然后人工翻译成OD那种代码,然后跟OD里比较下跟你想的有没有大的出入。

另,汇编代码起始入口处和CodeStart标记是否一致呢,如果不一致,那么这个问题我这样也能解释的通。
2009-12-26 10:40
0
雪    币: 75
活跃值: (803)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
11
知道是哪里出问题了,invoke函数在处理标号作为参数的时候有点小问题

start:
mov eax,CodeLength
                                                       
push CodeLength
push offset szTxt
push offset Buffer
call wsprintf
invoke wsprintf,offset Buffer,offset szTxt,CodeLength
invoke MessageBox,NULL,offset Buffer,NULL,MB_OK                                                                                       
invoke ExitProcess,NULL
end start
看生成的汇编代码
00401088 >/$  B8 88000000   mov     eax, 88
0040108D  |?  68 88000000   push    88
00401092  |?  68 14204000   push    00402014                         ;  ASCII "%d"
00401097  |?  68 00304000   push    00403000
0040109C  |?  E8 35000000   call    <jmp.&user32.wsprintfA>
004010A1  |?  68 A1000000   push    0A1
004010A6  |?  68 14204000   push    00402014                         ;  ASCII "%d"
004010AB  |.  68 00304000   push    00403000                         ; |Text = ""
004010B0  |.  E8 21000000   call    <jmp.&user32.wsprintfA>          ; |hOwner
004010B5  |?  83C4 0C       add     esp, 0C
004010B8  |?  6A 00         push    0
004010BA  |?  6A 00         push    0
004010BC  |?  68 00304000   push    00403000
004010C1  |?  6A 00         push    0
004010C3  |?  E8 14000000   call    <jmp.&user32.MessageBoxA>
004010C8  |?  6A 00         push    0
2009-12-26 14:06
0
雪    币: 444
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
004010A1  |?  68 A1000000   push    0A1

invoke函数在处理标号作为参数的时候有点小问题


学习了,还有这种问题啊。当初我看到你的代码 CodeLength = CodeEnd - CodeStart 时,感觉挺别扭的。建议你以后用用  CodeLength  DD  (CodeEnd - CodeStart) 这种方式。
2009-12-26 23:23
0
游客
登录 | 注册 方可回帖
返回
//