News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Olly plays foul

Started by jj2007, May 01, 2010, 07:41:50 AM

Previous topic - Next topic

jj2007

Same code, seen with Olly versions 1 (of 23.5.2004)+2 (3.12.2009):

00401049       |.  56                  push esi                                ; |Arg1 = 00142C00
0040104A       |.  E8 04150000         call 00402553                           ; \ForOlly1.00402553

00401049  |.  56            push esi                                 ; |Arg1 = ASCII "\zip_temp\mdg_test.csv "
0040104A  |.  E8 04150000   call 00402553                            ; \ForOlly2.00402553

Both executables run fine without Olly...
When launched with Olly 1, esi points to roughly the same memory area (00142C00 instead of 00142C20), but that memory is still virgin, meaning that before that something went seriously wrong.
Anybody else had that experience?

Ghandi

Stupid question but i have to ask, do you have any breakpoints set from a previous debug session which are now corrupt? I constantly have to remove my breakpoints and reset them because i edit the code and then upon reloading into the debugger the existing ones are pointing to neverland. Leaving these set can have some unpredictable results, otherwise i don't know why Olly would be doing that.

HR,
Ghandi

jj2007

Your question is not stupid at all, but that is not the reason. I mostly use int 3 as breakpoints, and even if I delete the udd and bak files, the error persists.
I attach the executable and a file for the commandline. The point where esi should be the commandline arg is after the 10 nops.

BlackVortex

Seems to be the same flow to me, it works fine on all cases.

With both ollies, the argument I give it is found and finally passed to ESI here :
0040103F  |.  8BF0          MOV ESI,EAX

Then after the nops it gets pushed correctly as a parameter.

You mean it doesnn't work for the old Olly on your system ? Maybe some heap corruption ? Usermode debuggers use different heap options ...

P.S.: I hope I understood the problem properly. Also, the argument is disregarded, right ?

http://www.symantec.com/connect/articles/windows-anti-debug-reference

jj2007

Which Olly1 version do you have? Same date, 23 May 2004?

BlackVortex

Quote from: jj2007 on May 01, 2010, 09:32:14 AM
Which Olly1 version do you have? Same date, 23 May 2004?
Yes. I'm on win7 x64 and using stealth64 plugin with the x64 compatiibility option

So, who knows ...   :bg

qWord

It is often helpful to delete the corresponding *.udd-file from Olly's directory for solving strange problems.

qWord
FPU in a trice: SmplMath
It's that simple!

jj2007

Quote from: qWord on May 01, 2010, 02:49:50 PM
It is often helpful to delete the corresponding *.udd-file from Olly's directory for solving strange problems.

qWord

That's true but doesn't help in this case. Further investigation showed that the two Olly versions initialise registers differently - which shouldn't be a problem, of course, but it seems that my app relies on esi being positive at ModuleEntryPoint or something like that. It's commonly called a bug :toothy

Ghandi

Sorry for the late reply JJ, i tested your executable with the Olly which i use on my PC, it is dated: "Saturday, May 22, 2004, 11:10:00 PM"

It behaves the same for me, where ESI is pointing to heap memory which is allocated but where the commandline is copied to this buffer the contents weren't present, instead only being the filler bytes 0xEE 0xFE.

I am curious about your explanation though. I have written a few little projects which make use of the debug API and have never read or heard of having to initialize registers for the debuggee. Can you explain this a little more please?

HR,
Ghandi

jj2007

Hi Ghandi,
I have no experience with the debug API but I assume the debugging starts with a CreateProcess and DEBUG_PROCESS in the param list. The content of registers at this moment is in the hands of the programmer, so that would explain why different versions of Olly can "initialise" the registers differently. My problem was that esi should have been explicitly set by my own app, instead of letting this be done by Olly.
Now that was clearly my bug; on the other hand, in principle the debugger (Olly) should pass on exactly the same register values to the app that it would get had Windows itself used CreateProcess. Which opens up an interesting argument, i.e. if a programmer should rely on having registers set to specific values at module entry point (NO).

Ghandi

At no point are the registers initialized (directly) by a debugger, it is still in the hands of Windows or the developer of the debugger. If Oleh has explicitly initialized the registers using SetThreadContext, i'm sure he'd have reasons, but it would be surprising to find that he did because it is a debugger and should try to be as transparent as possible to allow viewing the application in its 'native' context. Possibly it is a bug of his own doing?

HR,
Ghandi


jj2007

Quote from: Ghandi on May 28, 2010, 01:56:38 PM
At no point are the registers initialized (directly) by a debugger

The ABI says that Windows won't change esi edi ebx. At least I thought so... but it seems you are right: At module entry point, you will no longer see what you put in these regs before calling CreateProcess. You get garbage, fullstop.

Ghandi

Thats because the main thread has had to load libraries, such as ntdll and kernel32. Although your value was in the registers at startup, the thread still had to load modules and call the entrypoint of the program. If you want the registers to be the values you set and you don't want to debug the windows loader, you'll need to set them once the process is at entrypoint or at the first TLS callback if any are present.

HR,
Ghandi

jj2007

Quote from: Ghandi on May 29, 2010, 12:18:31 AM
Thats because the main thread has had to load libraries, such as ntdll and ..
Whatever. The important conclusion is "the ABI is valid but not before the entry point". Don't pass values in esi edi ebx to a thread or new process.

Ghandi

#14
I'm sorry but there seems to be confusion. You cannot pass values to a child process via registers. The only way to do so without hacking into the Windows kernel is to explicitly set the registers via SetThreadContext/ZwSetContextThread (or some derivitive) after it has reached TLS/Entrypoint or to pass a pointer through the STARTUPINFO structure used in the call to CreateProcess. Therefore the ABI does hold true and i cannot recall ever seeing anything documented about pre-entrypoint behaviour, because that is OS specific and i can't imagine Microsoft sharing that knowledge, hehe. :D



HR,
Ghandi