Log in

View Full Version : SI complete beginner question


plinius
November 11th, 2005, 11:42
Hello,

when you close notepad, you allways have a messagebox which asks if you want to save or not.

What I want to do is change the head-text of the messagebox with SI.
So I did "bpx messageboxw", which breaks just before the msgbox is displayed.
Code:
int MessageBox(
HWND hWnd,
LPCTSTR lpText,
LPCTSTR lpCaption,
UINT uType
);

My questions:
1) how can I change the head-text?
2)I allso want to change the buttons. Normally a 4 is pushed (yesnocancel), so I have to change this value to a 3 or sth else...

Can someone describe easily how I should do these two ?

thanks in advance.

naides
November 11th, 2005, 13:45
OK first tings first: With softice you cannot or should not change the head-text parameter value.
Let me explain, Yes you can modify the value in the stack, when you break inside the messagebox code, lets say from 4 to 3 and temporarily change the behavoir of the messagebox this time around, but next time notepad runs, it will be back pushing 4.
What you can do with softIce is , by keep tracing until messageboxW returns to notepad code, figure out the instruction(s) that PUSH that 4 parameter into the stack, modify it so it pushes a 3 instead (This is just an example), then write the changes permanently into the Notepad code.
Softice will not do this for you, you need to hex Edit the notepad.exe file (HIEW for instance).

plinius
November 11th, 2005, 14:13
Sorry if I explained it wrong, but that is what I want to do. I know that the code you see in softice is in the memory, and that the changes aren't permanent.

I tried to search where to change the title, but first
messageboxw
is called, and then:
messageboxexw.
I searched on msdn but didn't found any difference, you can use both to make a msgbox pop up, so why the two calls? (maybe messageboxw is a wrapper to messageboxexw ?!)

What I allso don't understand is the following:

code before 2nd call (the one to messageboxExW):
PUSH 00
PUSH DWORD PTR[ESP+14]
PUSH DWORD PTR[ESP+14]
PUSH DWORD PTR[ESP+14]
PUSH DWORD PTR[ESP+14]
CALL user32!messageboxexw

so, the 2nd to 5th argument should be the same??
And, how should I change/ find the headername to change?

Thanks for your help so far.

Plinius

Kayaker
November 11th, 2005, 14:58
Hi

Reply to your 1st post:

When you break on an API such as MessageboxW you can *immediately* display the stack in Softice with
dd esp

Each parameter can be accessed as offsets from the stack esp
esp+0, 4, 8 , 0C, 10, 14, ...

The first dword you see in the data window is always the return address. You can display the disassembly of that with
u *(esp+0)

If you want to view the lpCaption parameter for example, that will be in the 4th parameter on the stack. Display it with
d *(esp+0c)
or start editing it directly with
e *(esp+0c)
You want to edit the _contents_ of the stack variable, which is why you use the "*" in the Sice statement.

If you want to change the uType parameter for the yes/no/cancel type of msgbox, you can access this parameter the same way. In this case you want to change the actual _value_ of the stack variable so you don't use "*"
e esp+10

If you want to change the return value from the API, you can just trace through it and change the returned value in EAX (for MessageBox you can hit F4 twice to refresh the Softice screen)
r eax

See the Using Softice and Softice Command Reference pdf's for further details on these and other commands.


Reply to 2nd post:

I'm not sure how you're getting that disassembly for MessageBoxExW. You're right, MessageBoxW is a wrapper for this internal function, this is very common. However you're disassembly *should* look like this:

PUSH 00
PUSH DWORD PTR [EBP+14]
PUSH DWORD PTR [EBP+10]
PUSH DWORD PTR [EBP+0C]
PUSH DWORD PTR [EBP+08]
CALL _MessageBoxExW

That confusion is a problem with the disassembly output you're looking at, which disassembler?


Kayaker

plinius
November 11th, 2005, 15:40
Thanks a lot for your comment, you helped a lot.

So, just to make sure I got it correct, the * means the same as in C:
*(esp+10) : what was pointed to by the pointer which starts at esp+10 ..?

Quote:

That confusion is a problem with the disassembly output you're looking at, which disassembler?

->it was code I typed over (but not entirely correct....) from Soft-ice,

It had this form:

user32!messageboxw
push dword ptr[esp+14]
push dword ptr[esp+14]
push dword ptr[esp+14]
call user32!messageboxexw
ret 0010
NOP's (don't understand why)
mov eax, eax
push ebp
mov ebp,esp
push ff
PUSH DWORD PTR [EBP+14]
PUSH DWORD PTR [EBP+10]
PUSH DWORD PTR [EBP+0C]
PUSH DWORD PTR [EBP+08]
CALL user32!messageboxtimeoutW

(I think I copied it correct now, it's annoying there isn't an export-function in softice)

LLXX
November 11th, 2005, 19:29
1. This is easy.
If you want to change that text, open Notepad in a resource editor and look through the string table for the solitary entry "Notepad". Change it to e.g. "Goatpad", save, and test it.

2. All the push 4 (6a 04) in the Notepad that I have aren't for a MessageBox, so it must be a pushed memory address that contains a 4.

MessageBoxEx is almost identical to MessageBox, but it has an additional parameter:
Quote:
int MessageBoxEx(

HWND hWnd, // handle of owner window
LPCTSTR lpText, // address of text in message box
LPCTSTR lpCaption, // address of title of message box
UINT uType, // style of message box
WORD wLanguageId // language identifier
);

vs.
Quote:
int MessageBox(

HWND hWnd, // handle of owner window
LPCTSTR lpText, // address of text in message box
LPCTSTR lpCaption, // address of title of message box
UINT uType // style of message box
);

plinius
November 11th, 2005, 19:41
Quote:
[Originally Posted by LLXX]1. This is easy.
If you want to change that text, open Notepad in a resource editor and look through the string table for the solitary entry "Notepad". Change it to e.g. "Goatpad", save, and test it.


Thanks, but I'm trying to do it in softice, to learn the program...

JMI
November 11th, 2005, 20:41
I believe the point is that if you do not understand correctly how the API works you will not correctly understand what you see in Softice and will be confused about how or what you may or can change. So it's not just about how the debugger works. It's about how the debugger works with the code you are examining and want to edit.

Regards,

plinius
November 12th, 2005, 20:37
Quote:
[Originally Posted by JMI]I believe the point is that if you do not understand correctly how the API works you will not correctly understand what you see in Softice and will be confused about how or what you may or can change. So it's not just about how the debugger works. It's about how the debugger works with the code you are examining and want to edit.

Regards,


I think I know how the API works... first the arguments are pushed and then the function is called. I just didn't knew where to find the string that was pusehed using softice...
But Kayaker made this clear for me. Thanks, Kayaker.

naides
November 13th, 2005, 08:15
Quote:
[Originally Posted by plinius]I think I know how the API works... first the arguments are pushed and then the function is called. I just didn't knew where to find the string that was pusehed using softice...
But Kayaker made this clear for me. Thanks, Kayaker.



Just for sake of completion:
Appart from the method illustrated by kayaker to find the style string that was pushed, there is another strategy:


in Sice type WS (Window Stack): You will see a series of addresses in the call stack oredered from top to bottom: The top one is your current EIP , the second one points to the instruction immediately after the 'call' that took you to the current API, the next one points to the caller of the caller, and so on (If there are SEH involved, it does not work this way, be aware)
if you click into the second line in Sice stack window, the code window goes to the address that called your API: You can see the parameters being pushed etc etc etc


01001FA6 |. 74 27 JE SHORT notepad.01001FCF
01001FA8 |. 56 PUSH ESI ; /Arg3
01001FA9 |. FF75 14 PUSH DWORD PTR SS:[EBP+14] ; |Arg2
01001FAC |. FF75 10 PUSH DWORD PTR SS:[EBP+10] ; |Arg1
01001FAF |. E8 4EFFFFFF CALL notepad.01001F02 ; \notepad.01001F02
01001FB4 |. FF75 18 PUSH DWORD PTR SS:[EBP+18] ; /Style
01001FB7 |. FF75 0C PUSH DWORD PTR SS:[EBP+C] ; |Title
01001FBA |. 56 PUSH ESI ; |Text
01001FBB |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hOwner
01001FBE |. FF15 68120001 CALL DWORD PTR DS:[<&USER32.MessageBoxW>>; \MessageBoxW YOU ARE INSIDE HERE
01001FC4 |. 56 PUSH ESI ; /hMemory



this code snip comes from olly but you get the picture.
If you want to know who provides the style parameter at EBP+18 you etiher look up in the code or trace back to the caller caller function in the call stack until you find what you want.

This is a convenient way to move between the layers of caller and callee traces

or "ascend" the code

plinius
November 13th, 2005, 14:12
Thanks!
I'll download ollydbg and try it... maybe I like it.
If I got it correct, the only advantage of sice is that it's (allso) a kernelmode debugger (unlike olly).
So, for normal programs (no device drivers or ...) it doesn't matters which debugger to use??!

naides
November 13th, 2005, 14:31
Olly also has a stack view window, the workings are slightly different.

I personally find my way around Sice easier.
Also, certain tricks, like break on message: BMSG and break on port IO: BPIO which are very handy in locating protection schemes including dongle protection only work in Sice (As far as I can tell, olly does not implement them Or does it?).

Point is, it is not question of choice, get Sice AND Olly, learn both (I am lazy, I find olly a little bit cumbersome) and use the other when Sice (or Olly) does not take you where you want to go.