所以我正在阅读有关如何创建结构的手册..
起初,我做了:
struc point X, Y
{
.X dw X
.Y dw Y
}
section '.code' code readable executable
main:
push ebp
mov ebp,esp
PP Point 0, 0 ;Crashes here..
mov esp, ebp
pop ebp
mov eax, 0x0
ret
所以我认为很好,因为它是一个局部变量,我需要sub esp, sizeof(Point)
我做了,它仍然崩溃..
所以我在Point结构中完成了它而不是崩溃,它现在被删除了:
section '.data' data readable writeable
Response db 13, 10, "Value: %d", 13, 10, 0
struc Point X, Y
{
sub esp, 0x8
mov dword[esp + 0x00], X
mov dword[esp + 0x04], Y
}
section '.code' code readable executable
main:
push ebp
mov ebp,esp
PP Point 0, 0 ;create a point
push PP
call Point_Valid
add esp, 0x04
mov esp, ebp
pop ebx
call [getchar]
mov eax, 0x00
ret
Point_Valid:
push ebp
mov ebp, esp
mov eax, [ebp + 0x8]
push eax ;Not sure how to get Point from eax or Point.X..
push Response
call [printf]
add esp, 0x08
mov esp, ebp
pop ebp
ret
然而,不仅上述失败,它还触发了这个:
来自Malware Defender for Windows 8.1
我不明白为什么:S但只有当我在结构中使用sub esp
时才会发生。如果我使用.X dw X
它只是崩溃但不会触发恶意软件防御者。
任何想法如何实现将点传递给函数?或创建本地点并将其传递给函数以及访问其字段?
答案 0 :(得分:1)
在这两个变体中,您可以定义不同的东西。在第一个变体中,您在代码中创建数据,然后尝试执行它。只要变量包含随机指令(检查调试器),代码就会崩溃。我建议在程序的数据部分中移动变量 - 默认情况下它必须驻留在那里。
在第二次尝试中,您将数据替换为指令(尽管此处不必使用结构),然后正确执行代码。它是有效的代码。
你的AV不喜欢这个代码的事实是AV制造商的恕我直言的问题。我的建议是完全卸载它。
事实上,FASM经常遇到AV问题,假设什么是“好代码”,什么是病毒。请注意,所有这些都是误报。
答案 1 :(得分:1)
在第一个示例中,您将point
拼错为Point
,因此它没有组合(除非您告诉汇编程序忽略大小写)。
如果我们忽略了这一点,你在这里做了什么:
main:
push ebp
mov ebp,esp
PP point 0, 0 ;Crashes here..
mov esp, ebp
pop ebp
mov eax, 0x0
几乎和你写的一样:
main:
push ebp
mov ebp,esp
dw 0,0
mov esp, ebp
pop ebp
mov eax, 0x0
它只是将这两个0字插入指令" stream"你放在哪里。如果你组装它然后反汇编输出你得到:
00000000 6655 push ebp
00000002 6689E5 mov ebp,esp
00000005 0000 add [bx+si],al ; <- the first 0
00000007 0000 add [bx+si],al ; <- the second 0
00000009 6689EC mov esp,ebp
0000000C 665D pop ebp
0000000E 66B800000000 mov eax,0x0
00000014 C3 ret
您的pp
变量必须在其他地方声明,以便它永远不会在代码路径中结束(即eip / rip
不应该到达您的变量。)
如果您确实需要堆叠分配point
,则可以使用virtual at
:
virtual at esp-0x10 ; use whatever address is appropriate in your case
pp point 1,2
end virtual
mov ax,[pp.X]
请注意,这既不会为point
分配空间也不会初始化{{1}};它只是设置名称 - 地址映射。