开发者

how to push a string address to stack with assembly, machine code

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?


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:

01003E21 PUSH 70
01003E23 PUSH winmine_.01001390
01003E28 CALL winmine_.0100400C

Replace it with JMP 01004A5F by double clicking on the PUSH 70 line: (don't write "winmine_.")

01003E21 JMP winmine_.01004A5F
01003E26 NOP
01003E27 NOP
01003E28 CALL winmine_.0100400C

At 01004A5F you inject your code:

01004A5F PUSH 0
01004A61 PUSH winmine_.01004A5F
01004A66 PUSH winmine_.01004A5F
01004A6B PUSH 0
01004A6D CALL DWORD PTR[010010B8] ;msgbox

And add the original code that you deleted when adding your jump at the entry point, then jump back to the normal program execution:

01004A72 PUSH 70
01004A74 PUSH winmine_.01001390
01004A79 JMP winmine_.01003E28

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:

01004A58 UNICODE "Hello",0

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)


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.


I think that you need to send the address to AX first and then push ax

mov ax,OFFSET string1  ;or use LEA ax,string1
push ax

so, to create your MessageBox you need to do:

mov ax,16            ;16 = Critical Icon (for example)
push ax
lea dx,title
push dx
lea dx,text
push dx
mov ax,0              ;0 is like NULL for the window's handle
push ax
call MesssageBox...
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜