The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: baltoro on December 08, 2010, 01:21:00 AM

Title: An actual assembly programming question
Post by: baltoro on December 08, 2010, 01:21:00 AM
I'm wondering if there is a way to do this: in my program, I have called LoadLibrary, and GetProcAddress for a function that is exported from kernel32.dll only in Windows Vista and higher. Assuming the program is running on Windows Vista or higher, and GetProcAddress succeeds, is there any way that I can use the address with invoke?
In C++, typically you cast the return address into a function prototype (so that the compiler automatically checks the signature and parameters for correctness), and then call the function as if it were a normal dynamic DLL export. It's just for convenience, really. I was researching the question in Kip Irvine's: Assembly Language for Intel-Based Computers, and he says that you just use the address as an operand with the call instruction.
Title: Re: An actual assembly programming question
Post by: drizz on December 08, 2010, 01:42:05 AM
Of course you can and yes type checking will work too. http://www.masm32.com/board/index.php?topic=5299.msg39702#msg39702
Title: Re: An actual assembly programming question
Post by: dedndave on December 08, 2010, 03:25:29 AM
there is no need to use LoadLibrary for kernel32
it is already loaded   :bg
i use GetModuleHandle and GetProcAddress in a similar way to see if the OS supports multiple processors
if kernel32.dll contains SetProcessAffinityMask, then it does   :U

here is an example...

http://www.masm32.com/board/index.php?topic=14674.msg118929#msg118929

here is the lowdown, straight from the horses mouth   :P

http://www.masm32.com/board/index.php?topic=14674.msg118941#msg118941
Title: Re: An actual assembly programming question
Post by: hutch-- on December 08, 2010, 03:54:59 AM
 :bg

Have a look at the "SPROTO MACRO func_addr:REQ,arglist:VARARG" docmented in the high level help file with masm32.
Title: Re: An actual assembly programming question
Post by: dedndave on December 08, 2010, 04:00:28 AM
again - kernel32 is already loaded
if you use LoadLibrary, you should FreeLibrary later on
that is an unnecessary step, as the library is already loaded - and stays loaded
just use GetModuleHandle

however...
for what you are doing, you might be better off to use GetVersion or GetVersionEx
then, test for a minimum value of the major OS version number
Title: Re: An actual assembly programming question
Post by: dedndave on December 08, 2010, 04:15:22 AM
relying on the existance of a module to determine the OS version is not 100% reliable
one thing that is possible - MS released a hotfix for XP that adds the function to the API
then, your code will be broken   :P

here is a simple program...
Title: Re: An actual assembly programming question
Post by: hutch-- on December 08, 2010, 06:30:53 AM
 :bg

Every time I have seen people try shortcuts like that it comes back later and bites them on the ass. The overhead cost of a LoadLibrary() call is trivial and by doing this the published method it increments the module count up by one and on FreeLibrary() down by 1.
Title: Re: An actual assembly programming question
Post by: dedndave on December 08, 2010, 06:49:08 AM
kernel32.dll is always loaded - no matter what
and, it is always loaded first (per Edgar)
i am fairly certain it is the module that is responsible for loading and executing EXE's
i think that's part of the definition of a kernel

http://www.masm32.com/board/index.php?topic=14674.msg118988#msg118988

Quote.data

.code
Start:
invoke user32.dll:MessageBoxA,0,"hello",0,0
ret
(http://a.imageshack.us/img44/2057/kern32.jpg)
Title: Re: An actual assembly programming question
Post by: dedndave on December 08, 2010, 06:58:35 AM
        .DATA
szKernel32Module db 'kernel32.dll',0

        .CODE
Start:
        INVOKE  GetModuleHandle,offset szKernel32Module
        ret

        END     Start


you can assemble that as console or windows app
run it on any win OS that supports PE
and it will return a valid handle
Title: Re: An actual assembly programming question
Post by: hutch-- on December 08, 2010, 07:07:21 AM
Hate to tell you this but later Windows versions handle the instance handle from the main process. GetModuleHandle() is mainly retained for compatibility reasons. Its fine under NT based OS versions to assume the the "Colonel" will be loaded first but we have seen change in the internal structures of Windows over the last 15 years and Vista/Win7 is not an NT based kernel any longer. Wait for a later OS version to jump up and bite you on the arse for making that assumption.
Title: Re: An actual assembly programming question
Post by: japheth on December 08, 2010, 07:09:54 AM
Quote from: dedndave on December 08, 2010, 06:58:35 AM
you can assemble that as console or windows app
run it on any win OS that supports PE
and it will return a valid handle

Of course, since "GetModuleHandle" is exported by kernel32.dll. But this code:


.386
.model flat,stdcall
.code
start:
ret
END start


is also a valid Win32 binary, and here it is NOT guaranteed that kernel32 is loaded. In WinXP it is loaded, but for future Windows versions it might be just ntdll.dll. So using LoadLibrary is - theoretically - safer than GetModuleHandle.
Title: Re: An actual assembly programming question
Post by: jj2007 on December 08, 2010, 07:51:20 AM
Quote from: drizz on December 08, 2010, 01:42:05 AM
Of course you can and yes type checking will work too. http://www.masm32.com/board/index.php?topic=5299.msg39702#msg39702

Interesting technique, although it assumes that the lib is available and included (which is the case for the OP). Another option is a macro à la MasmBasic; it counts the paras passed, too:

Quote   Dll "msvcrt"
   Declare sprintf, C:?   ; C calling convention, variable # of args
   void sprintf(offset msgtext, "%016I64u", i64)      ; low & high dword of i64 managed by macro
   Print offset msgtext, 13, 10

Masm32 syntax for static link would be invoke crt_sprintf, offset msgtext, offset format, i64
Title: Re: An actual assembly programming question
Post by: dedndave on December 08, 2010, 09:06:29 AM
there is an excellent definition of the term "kernel" on wikipedia
but, i know Hutch will poo-poo on that - lol
so, i found a different source   :bg

http://www.webopedia.com/TERM/K/kernel.html

Quotekernel

The central module of an operating system. It is the part of the operating system that loads first, and it remains in main memory. Because it stays in memory, it is important for the kernel to be as small as possible while still providing all the essential services required by other parts of the operating system and applications. Typically, the kernel is responsible for memory management, process and task management, and disk management.

i wonder what you guys think the kernel is - lol
Title: Re: An actual assembly programming question
Post by: japheth on December 08, 2010, 09:40:55 AM
Quote from: dedndave on December 08, 2010, 09:06:29 AM
i wonder what you guys think the kernel is - lol

NTOSKRNL.EXE perhaps?  :bg
Title: Re: An actual assembly programming question
Post by: drizz on December 08, 2010, 12:40:26 PM
Quote from: dedndave on December 08, 2010, 09:06:29 AM
i wonder what you guys think the kernel is - lol
Bytes above SYSTEM_INFO.lpMaximumApplicationAddress and below SYSTEM_INFO.lpMinimumApplicationAddress   :bg

What you want to know ....

usermode:
somedll -> ntdll -> sysenter(id) -> dispatcher defined by some MSR

kernel:
dispatcher calls SSDT(id)
SSDT with
win32 subsystem -> mapped to NTOSKRNL.EXE or NTKRNLPA.EXE
win32k syubsystem -> win32k.sys :: gdi stuff

bla bla bla  :boohoo:
Title: Re: An actual assembly programming question
Post by: hutch-- on December 08, 2010, 01:12:57 PM
 :bg

> i wonder what you guys think the kernel is - lol

I always thought the "Colonel" had something to do with Kentucky Fried Chicken.
Title: Re: An actual assembly programming question
Post by: dedndave on December 08, 2010, 01:14:05 PM
some example code from microsoft....

http://msdn.microsoft.com/en-us/library/ms724429%28VS.85%29.aspx

would you like a hot apple turnover with that ?
perhaps i could interest you in some nice crow
Title: Re: An actual assembly programming question
Post by: hutch-- on December 09, 2010, 01:46:44 AM
 :bg

Ah, here is a man who has not sufered Microsoft changes from Win3.0, 3.1, NT4, Win95oem, Win95a, Win95b, Win95c, Win98, Win98se, Win2000, WinXP (SP1/2/3) Vista, Win7 etc ....

We would both grow old listing the changes across this many versions and remember that from Vista onwards the old NT "Colonel" is no longer used. The experience would not be "Finga likkin good".  :P
Title: Re: An actual assembly programming question
Post by: dedndave on December 09, 2010, 02:28:51 AM
well - you can't write all your code for some non-existant OS - lol
are you telling me that vista and win 7 do not use kernel32.dll ???
Title: Re: An actual assembly programming question
Post by: oex on December 09, 2010, 09:54:27 AM
Quote from: dedndave on December 09, 2010, 02:28:51 AM
well - you can't write all your code for some non-existant OS - lol

Sounds like heaven to me.... Just think of al the bugs er features you wouldnt have to work around :lol
Title: Re: An actual assembly programming question
Post by: baltoro on December 09, 2010, 06:12:15 PM
WOW,...this is great !!!
Thanks guys for all the information,...
...I think the code in drizz's response is what I'm looking for.

And, here's the reason I asked: I'm writing a DLL component in assembly language that determines processor characteristics, Operating System version, and security context information. I'm translating a component class that I wrote in C++. To improve on my original class. I'm adding various code blocks that I've located by searching the MASM forums,...just attributing the various code blocks to the original coders is taking up alot of the actual space in my asm file. For example: I've shamlessly stolen this cool concept: CPU Identification Code (http://www.masm32.com/board/index.php?topic=14754.0), from Antariy (actually, I sent him a forum message, and he says it's OK with him). 
The basic concept is to have a working code library that works correctly for any Windows Operating system, from Windows 95 on. So, yes, kernel32.dll is loaded into all process address spaces, but, if I am running on, say, Windows XP, and I call this function (GetProductInfo (http://msdn.microsoft.com/en-us/library/ms724358(v=vs.85).aspx)) in my code, it will FAIL. I think it will actually fail to compile, because the MASM32 header files don't prototype the function, and the current libraries I have installed on my computer (I'm still running Windows XP) don't export this function. Hence, the LoadLibrary and GetProcAddress approach, which (and, even Microsoft recommends this technique in their documentation) should work on all Windows versions, even Windows Vista and Windows 7. On previous operating systems I have a conditional code block that executes if GetProcAddress fails.
The reason I posted the question is that this situation comes up repeatedly, especially in respect to the User's security context.
The component is meant to be used as a preliminary scan of the overall system characteristics that might be significant from the general functionality of a program's execution. It's not really a good way to determine what specific functionality is available. Hutch is right about that,...you should use the LoadLibrary/GetProcAddress method for any of your application's critical requirements.
Title: Re: An actual assembly programming question
Post by: hutch-- on December 09, 2010, 09:38:02 PM
baltoro,

To satisfy the recent windows versions in security terms make sure you use a version control info block for the DLL so that the OS can recognise it and the shitty end of AV scanners have something to work on. A manifest file also helps in terms of recognition.
Title: Re: An actual assembly programming question
Post by: baltoro on December 10, 2010, 06:14:21 PM
Quote from: HUTCHTo satisfy the recent windows versions in security terms make sure you use a version control info block for the DLL so that the OS can recognise it and the shitty end of AV scanners have something to work on. A manifest file also helps in terms of recognition.

...that hadn't even occurred to me. Thanks again.