如何使用汇编、机器代码将字符串地址压入堆栈
我正在更改minesweeper.exe,以便了解代码注入的工作原理。简而言之,我希望扫雷器在开始之前显示一个消息框。因此,我在可执行文件中找到一个“洞穴”,然后定义要在消息框中显示的字符串并调用消息框。当然,此外,我还必须更改可执行文件的模块入口点的值,并首先将其定向到我的附加代码,然后继续其自己的代码。 所以在山洞里我所做的;
"hello starbuck",0
push 0 //arg4 of MessageBoxW function
push the address of my string //arg3, must be title
push the address of my string //arg2, must be the message
push 0 //arg1
call MessageBoxW
...
现在,由于每次将可执行文件加载到内存中时,可执行文件中代码的内存地址都会发生变化,因此为了调用 MessageBoxW 函数,我给出了导入地址表中定义 MessageBoxW 的地址的偏移量。例如,如果 MessageBoxW
在 IAT 中的 address1 处定义,并且 call MessageBoxW
之后的指令位于 address2 我没有编写call MessageBoxW
,而是编写了call address2 - address1
。
所以我的问题是,如何将字符串的地址推入堆栈? 例如,如果我通过 ollydbg 进行这些更改,我会给出“hello starbuck”的直接地址进行推送,并且它会起作用。但是在重新加载可执行文件或在 ollydbg 之外启动它之后,它自然会失败,因为直接地址发生了变化。
提前致谢, 伊吉特。
编辑:现在出现此问题是因为每次打开 exe 时模块入口点的高位字都会发生变化。因此,为了查看其他字符串是如何推入堆栈的,我这样做了:
我在代码中找到了“Destroy Canvas”字符串。它的地址是:00403E44。而在地址0042878E处,有指令PUSH 00403E44
(68 44 3E 40 00),这意味着指向字符串的指针被压入堆栈。然后我在UltraEdit中打开exe,找到了对应的地址,即00027D8E。在那里,它写的是“68 44 3E 00 01”,而不是“68 44 3E 40 00”。现在这意味着当 OllyDbg 加载 exe 时,它会更新这些代码; 00 01到40 00。我查看了其他字符串,它们的推送指令也是如此。所以我想也许如果我在 UltraEdit 中写“68 DA 9A 00 01”而不是“68 DA 9A 40 00”来推送字符串,它也会被更新。但事实并非如此。此后当我在 OllyDbg 中打开 exe 时,要推送的地址仍然是“01009ADA”。
所以我认为必须有一些东西来组织这些“更新代码”程序。也许这与重定位表有关,我不知道。
您认为也许我应该把这个问题作为另一个问题来问吗?
I am changing minesweeper.exe in order to have an understanding of how code injection works. Simply, I want the minesweeper to show a message box before starting. So, I find a "cave" in the executable and then define the string to show in messagebox and call the messagebox. Additionally of course, I have to change the value at module entry point of the executable and first direct it to my additional code, then continue its own code.
So at the cave what I do;
"hello starbuck",0
push 0 //arg4 of MessageBoxW function
push the address of my string //arg3, must be title
push the address of my string //arg2, must be the message
push 0 //arg1
call MessageBoxW
...
Now since the memory addresses of codes in the executable change everytime it is loaded in the memory, for calling the MessageBoxW function, I give the offset of the address where MessageBoxW is defined in Import Address Table. For instance, if MessageBoxW
is defined at address1 in the IAT and the instruction just after call MessageBoxW
is at address2
instead of writing call MessageBoxW
, I write call address2 - address1
.
So my question is, how do I do it for pushing the string's address to the stack?
For example, if I do these changes via ollydbg, I give the immediate address of "hello starbuck" for pushing and it works. But after reloading the executable or starting it outside of ollydbg, it naturally fails, since the immediate addresses change.
Thanks in advance,
Yigit.
Edit : Now this problem happens because the high-word of Module Entry Point changes everytime the exe is opened. So, in order to see how other strings are pushed to the stacks, I did this :
I found the "Destroy Canvas" string in the code. It is at the address : 00403E44. And at the address 0042878E, there is the instruction PUSH 00403E44
(68 44 3E 40 00) which means the pointer to the string is pushed to the stack. Then I opened the exe in UltraEdit, found the corresponding address, which is 00027D8E. There, instead of "68 44 3E 40 00", it writes "68 44 3E 00 01". Now it means that when OllyDbg loads the exe, it updates these codes; 00 01 to 40 00. I looked at the other strings, and their push instructions are likewise. So I thought maybe if I write "68 DA 9A 00 01" instead of "68 DA 9A 40 00" in UltraEdit in order to push the string, it'll be updated too. But it doesn't. When I open the exe in OllyDbg after this, the address to be pushed remains "01009ADA".
So I think there must be something which organizes these "updating code" procedures. Maybe it has something to do with the relocation tables, I don't know.
Would you think that maybe I should ask this as another question?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的解决方案:
您添加的字符串应该是 UTF-16。
对于字符串“Hello”,您应该写“Hello”,其中点为 00h。确保该字符串末尾至少有 00h00h00h(3 X 0)
还要确保当您调用 msgbox 时,您使用 dword ptr[] 调用它
CALL DWORD PTR DS:[10010B8]
详细信息:
在程序末尾,在 LoadLibrary 字符串(不是 unicode)附近,添加 UTF-16 格式的字符串,即每个 ASCII 字符以 00h 分隔,并且至少以 unicode 字符串结尾00h00h(00h 在 ollydbg 的转储窗口中由一个点表示)
在程序的入口点,您可能有这样的内容:
通过双击 PUSH 70 行将其替换为 JMP 01004A5F:(不要写“winmine_”。 )
在01004A5F处注入代码:
并添加在入口点添加跳转时删除的原始代码,然后跳回正常程序执行:
要找到MessageBoxW的地址,按CTRL+N,您将得到一个已注册函数的有序列表。
至于字符串,它看起来像这样:
享受。
原帖:
当您将字符串注入 exe 中时,在 OllyDbg 中尝试右键单击反汇编窗口并搜索 -> 所有引用文本字符串。
在那里您应该能够找到您的字符串及其地址。
您应该仔细阅读以下两篇文章:
http://osix.net/modules/article/ ?id=633
在本文的第 2 部分中,解释了如何使用您自己的消息替换 exe 中现有的(未使用的)字符串以及如何使用自定义函数调用它。
http://osix.net/modules/article/?id=758
在第 2 部分本文解释了文本部分和字符串以及如何引用它们。
这将为您提供足够的信息来开始逆向 Windows 应用程序。
作为逆转 Windows 游戏的奖励教程:
http://osix.net/modules/article/?id=723(空当)
Your solution:
The string you add should be UTF-16.
For string "Hello" you should write "H.e.l.l.o" the dot being 00h. Make sure that at the end of this string there are at least 00h00h00h (3 X 0's)
Also make sure that when you cal msgbox you call it with dword ptr[]
CALL DWORD PTR DS:[10010B8]
In details:
At the end of the program, near LoadLibrary string (which is not unicode), add your string in UTF-16, ie each ASCII character separated by 00h and with unicode string termination at least 00h00h (00h is represented by a dot in the dump window of ollydbg)
At the entry point of the program you probably have this:
Replace it with JMP 01004A5F by double clicking on the PUSH 70 line: (don't write "winmine_.")
At 01004A5F you inject your code:
And add the original code that you deleted when adding your jump at the entry point, then jump back to the normal program execution:
To find the address of MessageBoxW, press CTRL+N and you will get an ordered list of registered functions.
As for the string, it looks like this:
Enjoy.
Original post:
When you've injected your string in the exe, in OllyDbg try to right-click on the disassembly window and search->all reference text string.
There you should be able to find your string and its address.
Here are 2 articles that you should read carefully:
http://osix.net/modules/article/?id=633
In part2 of this article it is explained how you can replace an existing (unused) string in the exe with your own message and how to call it with your custom function.
http://osix.net/modules/article/?id=758
In part2 of this article there is an explanation about the text section and strings and how to reference to them.
That should give you plenty of informations to start resversing a windows application.
As a bonus tutorial on reversing windows games:
http://osix.net/modules/article/?id=723 (freecell)
如果字符串嵌入在 EXE 中,则其偏移量不应更改。它是作为资源加载还是动态分配还是什么?如果是后者之一,那么您需要推送动态创建的地址。但静态字符串应始终加载相同的偏移地址。
The offset of the string shouldn't change if it's embedded in the EXE. Is it loaded as a resource or dynamically allocated or what? If one of the latter, then you'd need to push the address created dynamically. But a static string should always load with the same offset address.
我认为您需要先将地址发送到 AX,然后推送 ax
,以便创建您需要执行的 MessageBox:
I think that you need to send the address to AX first and then push ax
so, to create your MessageBox you need to do: