Stop looking for the entry point at runtime in a DLL - windows

I have an application which runs on windows 2003, window 2008 and windows small business server.
There is a windows call that I make to reboot the system.All the calls mentioned below come from advapi32.dll
InitiateSystemshutdown - This is fine in windows 2003 and windows 2008 but for some reason not working in Windows aurora
InitiateShutdown - since the above call is not working in windows aurora we used this call and minimum supported OS for this call is windows 2008
Now my application fails to run in windows 2003 since the InitiateShutDown is not present in the advapi32.dll on Windows 2003
I get a failed to find procedure entry point for Initiateshutdown in advapi32.dll
I have already put a condition also so that the proper function calls are called with respect to the windows version.
Is there way to stop looking for the entry point in the dll when the application launches.The condition will make sure that the proper function call are called?
OR
I should be asking Microsoft why the old call InitiateSystemshutdown is not working properly ?

You have to use GetProcAddress and set your preprocessor variables for the earlier version of Windows. See http://msdn.microsoft.com/en-us/library/aa383745(VS.85).aspx#setting_winver_or__win32_winnt
Basically, you should:
Set WINVER to the earliest version of Windows you must support so you don't accidentally use something newer.
Some API calls and definitions won't work anymore (like InitiateShutdown in your case) in your code, because they aren't included by header files. For these, you must use them dynamically. Typically you use the GetProcAddress API and use a "typedef" to define the function's signature (since it isn't in the header files you're including anymore). An example is here: http://msdn.microsoft.com/en-us/library/ms683212(VS.85).aspx. In your case you would use the InitiateShutdown API instead of the given GetNativeSystemInfo. If the call to GetProcAddress fails then you can assume that the API is not supported on that version of Windows.

Rather that explicitly calling that function in your code (such that your app will fail to load if the function can't be loaded from the expected DLL), call it implicitly via LoadLibrary and GetProcAddress.
Do a "LoadLibrary" on advapi32.dll. And then call GetProcAddress for "InitiateShutdown". Fail gracefully if the function doesn't exist, otherwise cast it to an appropriate function pointer and
invoke it.
typedef DWORD (WINAPI *InitiateSystemShutdownTypeA) (char*, char*, DWORD, DWORD, DWORD);
typedef DWORD (WINAPI *InitiateSystemShutdownTypeW) (wchar_t*, wchar_t*, DWORD, DWORD, DWORD);
InitiateShutdownTypeA func = NULL;
HMODULE hMod = LoadLibrary("advapi32.dll");
if (hMod)
func = (InitiateShutdownTypeA)GetProcAddress("InitiateShutdownW");
if (func)
func(pwszMachineName, pwszMessage, dwGracePeriod, dwFlags, dwReason);

Related

windows kernel driver and undocumented API

I try to use an undocumented API while developing a windows kernel driver. Please don't tell me this is not the best thing to do ;)
Anyway, the undocumented API is PsGetProcessPeb that i found with IDA into ntoskrnl.exe
I define the following structures:
_PEB
_PEB_LDR_DATA
_LDR_DATA_TABLE_ENTRY
Also, I found that I have to define the function like:
NTKERNELAPI PPEB NTAPI PsGetProcessPeb(IN PEPROCESS Process);
The code (a part of) that I try to compile is:
PsLookupProcessByProcessId(ProcessId, &pProcess);
PPEB pPeb = PsGetProcessPeb(pProcess);
When i try to compile I get the following error code:
LNK2019
LNK1120: unresolved externals
The externals that is not resolved is PsGetProcessPeb
I guess that the linker doesn't find the function and doesn't know how to link.
The OS used to compile is Windows 10 build 19044 (x64) and I use Visual Studio 2019.
If you have any idea, please let me know.
Regards
The key to use an undocumented API is to find the API's address.
In kernelland, there is MmGetSystemRoutineAddress().
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-mmgetsystemroutineaddress
The MmGetSystemRoutineAddress routine returns a pointer to a function specified by SystemRoutineName.
Syntax
C++
PVOID MmGetSystemRoutineAddress(
[in] PUNICODE_STRING SystemRoutineName
);
Parameters
[in] SystemRoutineName
Specifies the name of the system routine to resolve.
Return value
If the function name can be resolved, the routine returns a pointer to the function. Otherwise, the routine returns NULL.
Remarks
Drivers can use this routine to determine if a routine is available on a specific version of Windows. It can only be used for routines exported by the kernel or HAL, not for any driver-defined routine.

WinMain entry point - VS Linker vs Windows API

I had been setting my application (MASM assembly language program) entry point via Visual Studio configurations, in the Project properties as:
Linker\System\SubSystem: Windows (/SUBSYSTEM:WINDOWS)
Linker\Advanced\Entry Point: WinMain
Any my main proc called WinMain (matching the above setting). It is a basic application that makes simple Windows API calls, e.g. MessageBoxA... and it works.
Now I'm building a Window application (in assembly), I read somewhere that I need to call the WinMain Windows API for an entry point.
I'm now confused! Which technique do I use to set the entry point to my application (exe)? The Windows API call 'WinMain' or the Visual Studio Linker entry point settings? And is the difference, i.e. C++ runtime vs OS?
If you are using the C runtime library (which is usually the case when programming in C) then you must not specify the linker entry point yourself. If you do, the runtime library will not be properly initialized, and any runtime library calls (including those inserted by the compiler) may fail.
Instead, your main function should correspond to the relevant standard: WinMain() for a GUI application, or main() for a console application.
In an assembly language program that is not linked to the C runtime library, you should specify an entry point of your choosing.
The signature of the native entry point is
DWORD CALLBACK RawEntryPoint(void);
Important:
Returning from the raw entry point implicitly calls ExitThread (see this answer) which is not usually the right thing to do, because if the Windows API has created any threads that you don't know about, the process won't exit until they do. Note that the Windows API documentation does not always indicate when a particular API function may cause a thread to be created.
Instead, you should explicitly call ExitProcess. This is what the C runtime library does when you return from WinMain() or main().

Access violation inside LoadLibrary() call

I encounter an access violation when calling a DLL inside LabVIEW. Let's call the DLL "extcode.dll". I don't have its code, it comes from an external manufacturer.
Running it in Windbg, it stopped with the message:
(724.1200): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
ntdll!RtlNewSecurityObjectWithMultipleInheritance+0x12a:
And call stack is:
ntdll!RtlNewSecurityObjectWithMultipleInheritance+0x12a
ntdll!MD5Final+0xedfc
ntdll!RtlFindClearBitsAndSet+0xdf4
ntdll!RtlFindClearBitsAndSet+0x3a8
ntdll!RtlFindClearBitsAndSet+0x4b9
ntdll!RtlCreateProcessParametersEx+0x829
ntdll!LdrLoadDll+0x9e
KERNELBASE!LoadLibraryExW+0x19c
KERNELBASE!LoadLibraryExA+0x51
LabVIEW!ChangeVINameWrapper+0x36f5
LabVIEW!ChangeVINameWrapper+0x3970
LabVIEW!ExtFuncDynLibWrapper+0x211
Note that dependencies of extcode.dll are loaded before access violation.
The situation is random, but when it happens all subsequent tries lead to it.
The code is a simple LabVIEW function calling a function in the DLL, and prototype is super simple (int function(void)) so it cannot be an misconfiguration of the call parameters, nor pointer arithmetics. I checked every combination of calling conventions and error checking levels.
The DLL runs perfectly fine when called in other environments (.NET and C).
I found that RtlFindClearBitsAndSet is related to bit array manipulations
What does it make you think about? Do you think it is a problem in extcode.dll, LabVIEW, or Windows?
PS: I use LabVIEW 2010 64 bit, on Windows 7 64 bit (and extcode.dll is 64 bit). I didn't manage to reproduce it on 32 bit system.
11/18 EDIT
I ended up making a standalone exe that wraps the DLL; LabVIEW communicates with it through pipes. It works perfectly, but I stil don't understand why loading a DLL into LabVIEW can crash.
If it works ok when called from C, you can quit working with Windbg because the DLL is probably ok. Something is wrong with how the DLL is being called, and once the DLL overwrites some of LabView's memory it is all over, even though it might take 1000 iterations before something actually goes kablooey.
First check your calling conventions, C or StdCall. C calling convention is the default and StdCall is almost certainly what you want. (Check the DLL header file.) LabView 2009 apparently did some auto-checking and fixing of calling conventions, but the switch to LLVM in LV 2010 has made this impossible; now it just tanks.
If it still tanks after changing this, check your calling arguments again. what you are passing, scalars or pointer data? You cannot access memory allocated by the DLL from LabView without doing some sneaky things, although you can allocate memory (i.e. byte array) in LabView and pass a pointer to it to the DLL for it to modify.
Also, if you are getting a pointer (such as a refnum) from an earlier call to DLL and returning it, check your pointer size. LabView's Call Library function now has a "pointer size integer" type, which generates the appropriately-sized type depending on whether it is invoked in 32-bit or 64-bit LabView. (It is always 64 bits on the wire, because that has to be defined at compile time.) The fact that your DLL works in 32 suggests this is a possibility.
Also keep in mind that C structs are often aligned by the (C) compiler. If you are passing a pointer to a struct made of a Uint8 and an UInt16, the C compiler will allocate 32 bits (or maybe even 64 bits) for this. You'll have to pad your struct (cluster) in LabView to make it match, or write a wrapper DLL to assemble the struct.
-Rob
An access violation (0xc0000005) will also be reported if DEP (Data Execution Prevention) is enabled on your machine and disapproves of something your binary (EXE or DLL) is trying to do. DEP is usually off by default on Windows XP, but active on Windows Vista / Windows 7.
DEP is a hardware-supported security measure designed to prevent malicious code executing some bytes that previously were considered "just some data"; I've had a few run-ins with it, all of which required re-compiling the offending binaries with a recent version of Microsoft Visual Studio; this allows to you set a flag which defines whether or not your binary supports DEP.
Some useful resources:
I found this MSDN blog entry
very helpful for gaining an
understanding of what DEP is and does
You might also want to consult this
technet article on how to turn
DEP on and off on Windows XP.
This is hard to diagnose remotely, but here are a couple of ideas.
The fact that your function takes no arguments means that either the function is truly trivial, or there is some stored state in the dll that takes into account previous function calls. Maybe the crash in this function is only an indicator, and you have a problem with a previous function call? Is there an initilization routine you're not calling?
If you only have problem when using 64 bit labview, my first guess would be that there's a problem with the 64 bit version of the dll, but if you are sure you don't have any problem with the exact same calls when using the dll in other environments, I'm stumped. One possibility is that you are using the wrong calling convention (stdcall vs. cdecl) in labview.
Have you tried importing the dll and header using the labview import wizard? This might help avoid silly mistakes with the prototypes.
One other thing to try: right click on the DLL call, choose configure and make sure you're running in the UI thread instead of any thread. Sometimes this helps.
When working with git and cygwin under NTFS, i found that sometimes the executable bit is not set (or un-set during checkout or some file operations) - inside cygwin cd to the folder and do
chmod a+rwx *.dll
and check if it changes a thing (and check if you want it this way!). I found this question while searching for LoadLibrary() failing with GetLastError() returning 5 (not "0xc0000005" btw) and solved the issue with this chmod call.

dynamically running a DLL at a remote Windows box?

Is there a way of dynamically running a DLL at a remote Windows box?
Say a user wants to send a his own DLL file to a remote server and run a function in that DLL at the remote site. The user may be able to provide function entry points as well as required parameters, but no more. (e.g. no header file)
I am thinking of setting up an agent executable at the remote site that can (1) dynamically load and bind a unknown DLL and (2) run a function with parameters. Is this a good a approach, or is such an executable possible?
You can use a technique of Dynamically loading your DLL's.
Normally you use a DLL by statically linking a .LIB into your project and compiling it. To load a DLL dynamically at runtime you use the following WIN32 API functions and a few other tricks.
LoadLibaray();
LoadLibarayEx();
GetProcAddress();
FreeLibrary();
There are some other tricks involved
You need to declare the dll functions as export'ed.
In c++ you need to use extern "C" to prevent name mangling of your functions.
FARPROC ... with GetProcAddress
It is all explained in the following wiki article - http://en.wikipedia.org/wiki/Dynamic-link_library
Your idea of installing an executable on the remote machine is a good one. So long as you agree on the function names and parameters with the user. If the dll complies with this then the dll can be changed at any time without requiring you EXE to be changed. Once set up and working it is simple to add extra functions.
Yes you could write small program that runs the DLL function using this information and call it remotely using the something like PSEXEC from sysinternals.
PsExec is a light-weight
telnet-replacement that lets you
execute processes on other systems,
complete with full interactivity for
console applications, without having
to manually install client softwareto manually install client software
Andrew Cash's reply is sound for unmanaged code. The technique he describes around GetProcAddress is essentially what RunDll32.exe does. RunDll32.exe is part of Windows and specializes at loading arbitrary DLLs and executing their code. You can run it like this:
RUNDLL32.EXE [dllfile],[entrypoint] [optional arguments]
When you do this, RunDll32 will call LoadLibrary on the DLL and then GetProcAddress on the entrypoint name you give it. If all that goes well then it calls the entry point function.
For this to actually work the entrypoint function needs to be exported. It must also be declared like this:
void CALLBACK MyEntryPoint(
HWND hwnd,
HINSTANCE hinst,
LPSTR lpszCmdLine,
int nCmdShow);

System calls on Windows

I just want to ask, I know that standart system calls in Linux are done by int instruction pointing into Interrupt Vector Table. I assume this is similiar on Windows. But, how do you call some higher-level specific system routines? Such as how do you tell Windows to create a window? I know this is handled by the code in the dll, but what actually happend at assembler-instruction level? Does the routine in dll calls software interrupt by int instruction, or is there any different approach to handle this? Thanks.
Making a Win32 call to create a window is not really related to an interrupt. The client application is already linked with the .dll that provides the call which exposes the address for the linker to use. Since you are asking about the difference in calling mechanism, I'm limiting the discussion here to those Win32 calls that are available to any application as opposed to kernel-level calls or device drivers. At an assembly language level, it would be the same as any other function call since most Win32 calls are user-level calls which internally make the needed kernel calls. The linker provides the address of the Win32 function as the target for some sort of branching instruction, the specifics would depend on the compiler.
[Edit]
It looks like you are right about the interrupts and the int. vector table. CodeGuru has a good article with the OS details on how NT kernel calls work. Link:
http://www.codeguru.com/cpp/w-p/system/devicedriverdevelopment/article.php/c8035
Windows doesn't let you call system calls directly because system call numbers can change between builds, if a new system call gets added the others can shift forward or if a system call gets removed others can shift backwards. So to maintain backwards compatability you call the win32 or native functions in DLLs.
Now there are 2 groups of system calls, those serviced by the kernel (ntoskrnl) and by the win32 kernel layer (win32k).
Kernel system call stubs are easily accessible from ntdll.dll, while win32k ones are not exported, they're private within user32.dll. Those stubs contain the system call number and the actual system call instruction which does the job.
So if you wanted to create a window, you'd call CreateWindow in user32.dll, then the extended version CreateWindowEx gets called for backwards compatability, that calls the private system call stub NtUserCreateWindowEx, which invokes code within the win32k window manager.

Resources