将字符串动态加载到本地变量
假设我创建了一个本地变量或者为字符串分配内存,现在我想在其中添加一个值。将字符串动态加载到本地变量
push ebp
mov ebp, esp
sub esp, 0xff ; 255 bytes
,并存储在堆栈中的字符串在C:
strcat(my_str1, "something1");
strcat(my_str1, get_var2());
strcat(my_str1, "something3");
strcat(my_str1, get_var4());
我想undertand怎么做,没有FASM或者NASM “的strcat”:
;1
mov byte ptr [esp - 1], 's'
mov byte ptr [esp - 2], 'o'
mov byte ptr [esp - 3], 'm'
mov byte ptr [esp - 4], 'e'
; and so on
这究竟是怎么完成?关于“get_var2()”和“get_var4()”的部分?
;2
call get_var2
mov ??byte?? ptr [esp - 11], eax
; or lea?
1)sub esp, 0xff
保持esp
排列,每4至少如果你需要C字符串只有255个字节(254个字符+ 0终结),然后分配256
2)mov [esp-1],'s'
你已经递减esp
,所以本地变量是在一些[esp+X]
地址(多少取决于你有多少其他值你推堆栈)。或者宁愿使用[ebp-Y]
与C类功能序幕,初始化ebp
第一个(push ebp
mov ebp,esp
sub esp,local_vars_size
..然后结尾mov esp,ebp
pop ebp
ret
)初始化堆栈帧指针。除非你确切地知道你在做什么以及为什么(例如在64b模式下写入红色区域),因为如果你不确定,那么在99%的情况下它会以错误结束,并且通常很难找到,这很少影响代码。
3)在NASM的4个MOVS是可以做到单DWORD不变mov [esp-4],dword 'emos'
(顺便说一句,你可能没有要设置'some'
?)
是的,这就是常见的方式编译器如何设置更短的常量在本地分配的堆栈空间,对于更大的数据,它们可以使用来自恒定模板数据的memcpy
。
4)约get_var2()
,所以get_var2()
返回稳定(char *)
指针?那么你将不得不重新实现完整的strcat
,除非你可以告诉字符串中已经有多少个字符,并且将添加多少个字符。如果get_var2()
返回一些值,你首先将它转换为一些字符,并决定多少,等等。然后你可以直接写它们,或者在某些循环等等。太宽泛。
另外,当在本地堆栈上运行时,如果超出边界并覆盖几个字节,我会在变量周围分配一些安全空间。你甚至可以首先将这些额外的字节设置为一些canary值,然后在函数结束时检查它,看看是否发生了一些堆栈覆盖(至少在调试版本中)。而不是strcat
然后您需要strncat
或类似的,以避免恶意数据堆栈溢出。
否则,正如Jester所建议的,也许试图首先在固定内存缓冲区上实现strcat
,这样您就可以专注于代码本身,而不是解析本地内存的分配。然后你可以建立它,甚至用它作为函数调用。
尝试在C中首先实现'strcat'(不使用任何库函数)。然后你会看到它是如何工作的,并且你可以在asm中做同样的事情。 – Jester