flat assembler
Message board for the users of flat assembler.

 Index > Windows > why eax==-1? Goto page 1, 2, 3  Next
Author
yinke

Joined: 07 Jan 2010
Posts: 7
yinke 09 Jan 2010, 09:15
Code:
format pe gui
include 'win32ax.inc'
entry start

fileName db 'E:\text.exe',0
hFile dd ?

start:
FILE_SHARE_WRITE,\
NULL,OPEN_EXISTING,0,0
cmp eax,INVALID_HANDLE_VALUE
jz lppt

lppt:
ret

library kernel32,'kernel32.dll'
include 'api\kernel32.inc'    

why eax==-1
09 Jan 2010, 09:15
bitshifter

Joined: 04 Dec 2007
Posts: 786
Location: Massachusetts, USA
bitshifter 09 Jan 2010, 09:48
Code:
GENERIC_READ or GENERIC_WRITE

Code:
invoke  CreateFileA,fileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL

To write a file that may or may not exist already...
Code:
invoke  CreateFileA,fileName,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL

Also use invoke ExitProcess,0 instead of ret

Hope that helps
09 Jan 2010, 09:48
Teehee

Joined: 05 Aug 2009
Posts: 570
Location: Brazil
Teehee 09 Jan 2010, 09:55
also use section .data at bottom. Some antivirus got virus alerts if you let it at top.

_________________
09 Jan 2010, 09:55
Tomasz Grysztar

Joined: 16 Jun 2003
Posts: 8099
Location: Kraków, Poland
Tomasz Grysztar 09 Jan 2010, 12:51
bitshifter wrote:
Also use invoke ExitProcess,0 instead of ret

That's not so good advice. Ending program with RET is perfectly legal in this case.
09 Jan 2010, 12:51
Pirata Derek

Joined: 31 Oct 2008
Posts: 259
Location: Italy
Pirata Derek 09 Jan 2010, 13:10
I'm agree with tomasz:

Automatically at application start, system sets the ESP pointing an offset to a kernel.dll library routine that terminates the thread (and so, the process)

the RET instruction will jump in that routine and the application execution is stopped.
09 Jan 2010, 13:10
f0dder

Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
f0dder 09 Jan 2010, 13:29
Tomasz and Pirata: that is depending on undocumented behavior. While not very likely to ever break, this is a pretty bad idea.

If you were linking against libc and using main/winmain, it'd be perfectly fine & documented... but that's a different story.
09 Jan 2010, 13:29
Pirata Derek

Joined: 31 Oct 2008
Posts: 259
Location: Italy
Pirata Derek 09 Jan 2010, 13:48
Yes, but documented or not it don't care:

why don't you assemble this simple program and, debug it with IDA pro and trace the execution after the RET?

maybe you find the operating system mechanism that close this process/thread, without problems.....

PLEASE: check the NtTerminateProcess and NtClose
(from XP to seven the mechanism is different)
09 Jan 2010, 13:48
Tomasz Grysztar

Joined: 16 Jun 2003
Posts: 8099
Location: Kraków, Poland
Tomasz Grysztar 09 Jan 2010, 14:01
f0dder: when you create a thread, it is called as a function you can return from, and it is perfectly documented. Since there is nowhere stated that the main application thread is somehow different from the other threads in this aspect, I assume this means we can take this behaviour to be documented.
09 Jan 2010, 14:01
f0dder

Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
f0dder 09 Jan 2010, 16:37
Pirata: I know how the stuff works, thank you - but it's still not documented. Just like some people thought they could get away with PE executable with no imports because "kernel32.dll is always injected"... well, try that on win2k.

Tomasz: documented for usermode thread creation functions, yes. But how your PE entrypoint is reached isn't documented - neither is it documented whether the executable loading is done in kernel or usermode. I think it's fairly safe MS isn't going to change the mechanics of the PE loader anytime soon, but depending on undocumented functionality tends to lead to breakage sooner or later.

And it's not like ExitProcess takes a lot of space in the import table, that the call takes lot of space or incurs measurable overhead compared to "ret", so you might as well play it safe unless you're writing 4kb intros
09 Jan 2010, 16:37
Tomasz Grysztar

Joined: 16 Jun 2003
Posts: 8099
Location: Kraków, Poland
Tomasz Grysztar 09 Jan 2010, 17:01
I think that main thread should not be discriminated from the other threads in such a way. No matter what creates it, it should behave the same. My opinion is: since it is not stated that this thread (though created through different mechanism) behaves differently than the ones you create yourself, we can assume it behaves the same, including the RET behaviour.
Well, it seems a little like interpreting the law. Anyway, that's my opinion - unless they document clearly that the main thread is different from the other threads in such a way, that it cannot be exited with RET, it's a perfectly valid assumption that it behaves just like any other. I would even argue, that we should be exiting the main thread with "RET 4".
09 Jan 2010, 17:01
LocoDelAssembly

Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 09 Jan 2010, 18:40
In Windows Super Sky 9 not calling ExitProcess could left the process in zombie state? (don't remember if this state is implemented on Windows)
09 Jan 2010, 18:40
Pirata Derek

Joined: 31 Oct 2008
Posts: 259
Location: Italy
Pirata Derek 09 Jan 2010, 19:45
The only thing i can tell to you is:

If you end a process or thread with RET and follow the execution (with a debugger), you give always the same RESULT:
The Process / Thread EXITS WITHOUT ANY KIND OF ERRORS.

I've done that about 20 times in many PEs.

This pratical consideration should answer at all, until you can prove the opposite case.
09 Jan 2010, 19:45
f0dder

Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
f0dder 09 Jan 2010, 20:16
Tomasz: Windows internals are not documented by MS - you aren't told if the main thread is created with CreateThread, CreateRemoteThread, ZwCreateThread, or something completely different. You're relying on the documentation of user-mode CreateThread. I don't have the DDK documentation handy right now, so I can't look up ZwCreateThread, but you can be pretty sure it doesn't lead to the same KERNEL32.DLL code that CreateThread does

It's the same kind of reasoning that leads to "Windows uses file mappings for the executable - I should be able to UnmapViewOfFile on my BaseAddress, then" - which works on some Windows versions and not others... You know part of the story, and some of it might even be partially documented - but you really shouldn't extrapolate from this.

LocoDelAssembly wrote:
In Windows Super Sky 9 not calling ExitProcess could left the process in zombie state? Razz (don't remember if this state is implemented on Windows)
It's not likely to happen in this example, but you don't have any guarantee it won't. It's mainly the mindset in general I'm against, but considering it costs you next to nothing to do things properly, then why not do it? If you do Windows development you should be following The Old New Thing, and if you do that you really should cringe whenever you see people depending on undocumented behavior

Piara Derek wrote:
This pratical consideration should answer at all, until you can prove the opposite case.
The same logic leads to "I've been struck by lightning 3 times, it's not something that kills you" or "I've done 100 acid trips, it's not dangerous to anyone". See your flaw? For something a bit more "realistic", I point you back to the PE-with-no-imports example... it works on all the Windows versions I tested - except Windows 2000. The precise rule on that OS is "you must end up importing from KERNEL32.DLL" - thus importing your own "null.dll" isn't good enough, but importing GDI32.DLL is since it ends up importing from KERNEL32.DLL (but you really shouldn't depend on that either, because it's not documented as a part of GDI32 ). This DLL dependency isn't documented as a requirement, but it still goes to show that there are differences between Windows versions, even for something so fundamental and "that'll never change!".
09 Jan 2010, 20:16
Tomasz Grysztar

Joined: 16 Jun 2003
Posts: 8099
Location: Kraków, Poland
Tomasz Grysztar 09 Jan 2010, 20:25
f0dder wrote:
Tomasz: Windows internals are not documented by MS - you aren't told if the main thread is created with CreateThread, CreateRemoteThread, ZwCreateThread, or something completely different. You're relying on the documentation of user-mode CreateThread. I don't have the DDK documentation handy right now, so I can't look up ZwCreateThread, but you can be pretty sure it doesn't lead to the same KERNEL32.DLL code that CreateThread does

There's nowhere said that the main thread is different from the other threads, and for the sake of this argument it doesn't really matter how it is created. If you couldn't rely on it being "thread" just like any other is, you couldn't even use ExitThread and be sure that it would work with it.
It really doesn't matter to me, whether it is CreateThread used to create it, or some custom kernel code - however what matters to me, is that it is still called "thread", and since there is nowhere stated that it is something different from the other ones, I feel obligated to treat it no differently than others. The fact how it was created should be transparent to the programmer.
09 Jan 2010, 20:25
LocoDelAssembly

Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 09 Jan 2010, 20:38
Tomasz, but you are using RET from ThreadProc right? So, what is documented is that you can simply RET from it without calling ExitThread. In the entry-point however, where are you told that there was some ThreadProc that called the entry-point or even the entry-point is a ThreadProc so you can just do RET?
09 Jan 2010, 20:38
Tomasz Grysztar

Joined: 16 Jun 2003
Posts: 8099
Location: Kraków, Poland
Tomasz Grysztar 09 Jan 2010, 21:06
I am nowhere told that ThreadProc is something applied only to thread created with CreateProcess. I treat it as something more general, that you have to have in mind when using CreateProcess, but should be true for all threads.
09 Jan 2010, 21:06
LocoDelAssembly

Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 09 Jan 2010, 21:42

Code:
DWORD WINAPI ThreadProc(
__in  LPVOID lpParameter
);    

What I mean is that you rely on the fact that you can return from ThreadProc, but since the entry point is NOT documented as ThreadProc, how do you conclude that RET will be always safe? (which should be "RET 4" if the "main" thread is even more equal to all other threads)

And another problem, doing just RET will be equivalent to ExitProcess, TerminateProcess or neither of both?

MSDN wrote:
If one of the terminated threads in the process holds a lock and the DLL detach code in one of the loaded DLLs attempts to acquire the same lock, then calling ExitProcess results in a deadlock. In contrast, if a process terminates by calling TerminateProcess, the DLLs that the process is attached to are not notified of the process termination. Therefore, if you do not know the state of all threads in your process, it is better to call TerminateProcess than ExitProcess. Note that returning from the main function of an application results in a call to ExitProcess.
( http://msdn.microsoft.com/en-us/library/ms682658%28VS.85%29.aspx )
09 Jan 2010, 21:42
Tomasz Grysztar

Joined: 16 Jun 2003
Posts: 8099
Location: Kraków, Poland
Tomasz Grysztar 09 Jan 2010, 22:05
LocoDelAssembly wrote:

Yes, my mistake.

LocoDelAssembly wrote:
What I mean is that you rely on the fact that you can return from ThreadProc, but since the entry point is NOT documented as ThreadProc, how do you conclude that RET will be always safe?

The fact that entry point is not documented to make thread with CreateThread doesn't mean it does not create a thread - it does. And my assumption is, since not told otherwise, that all threads are the same, thus I conclude that all threads have the ThreadProc-like structure, and the fact that you are told to use it with CreateThread is just a natural consequence of this fact. I simply exploit the fact that the documentation is incomplete here, and in my interpretetation (again - this starts to look a bit like interpreting the law by judge, etc.) the only logical conclusion is that every thread should be ThreadProc-like, because otherwise we would have some discrimination that would have no explanation in documentation (and I would consider that a bug).

LocoDelAssembly wrote:
And another problem, doing just RET will be equivalent to ExitProcess, TerminateProcess or neither of both?

Doing just RET should be equivalent to ExitThread only. It's a common behaviour to all threads, and hence also a logical conclusion from my above reasoning.
09 Jan 2010, 22:05
LocoDelAssembly

Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 09 Jan 2010, 22:36
Quote:

But then, why it is not "RET 4", as being a stdcall entry you should restore the stack?

Also note that the documentation mentions in some parts "main thread" (in CreateProcess, for example), so it is not clear why all threads should start the same way to me.

On the other hand there is something that could be backing you:
MSDN wrote:
How Processes are Terminated

A process executes until one of the following events occurs:

* Any thread of the process calls the ExitProcess function. Note that some implementation of the C run-time library (CRT) call ExitProcess if the primary thread of the process returns.
* The last thread of the process terminates.
* Any thread calls the TerminateProcess function with a handle to the process.
* For console processes, the default console control handler calls ExitProcess when the console receives a CTRL+C or CTRL+BREAK signal.
* The user shuts down the system or logs off.
09 Jan 2010, 22:36
yinke

Joined: 07 Jan 2010
Posts: 7
yinke 10 Jan 2010, 04:10
thank you
10 Jan 2010, 04:10
 Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First

 Jump to: Select a forum Official----------------AssemblyPeripheria General----------------MainTutorials and ExamplesDOSWindowsLinuxUnixMenuetOS Specific----------------MacroinstructionsOS ConstructionIDE DevelopmentProjects and IdeasNon-x86 architecturesHigh Level LanguagesProgramming Language DesignCompiler Internals Other----------------FeedbackHeapTest Area
Goto page 1, 2, 3  Next

Forum Rules:
 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot vote in polls in this forumYou cannot attach files in this forumYou can download files in this forum