LoadLibraryExW Fails to Load User32.dll - c

When trying to load C:\Windows\System32\user32.dll via LoadLibraryExW, it fails with the last error of ERROR_INVALID_IMAGE_HASH.
Here is how it is loaded:
HMODULE User32Lib = LoadLibraryExW(L"C:\\Windows\\System32\\user32.dll", NULL, LOAD_LIBRARY_REQUIRE_SIGNED_TARGET);
I looked at the DLL itself, and it was signed (for the version on my machine) on 8 April 2020 so it should still be valid.
Am I doing something incorrectly?

Apparently LOAD_LIBRARY_REQUIRE_SIGNED_TARGET requires the PE image to be linked with IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY (0x0080) in its DLL characteristics. This is a flag that forces the memory manager in the kernel to check for a digital signature when loading the image. Refer to the linker option /INTEGRITYCHECK.
Most of the system DLLs do not have this characteristic. "user32.dll" doesn't have it, but "bcrypt.dll" does:
PS C:\> $user32_hdr = get-peheader C:\Windows\System32\user32.dll
PS C:\> $bcrypt_hdr = get-peheader C:\Windows\System32\bcrypt.dll
PS C:\> '{0:x}' -f $user32_hdr.DllCharacteristics
4160
PS C:\> '{0:x}' -f $bcrypt_hdr.DllCharacteristics
41E0
I don't know much in particular about the subject of code signing and the implementation details in the loader and memory manager. I just used a debugger to discover that the load was failing with STATUS_INVALID_IMAGE_HASH in LdrpCompleteMapModule, after it checked for 0x80 in the DLL characteristics. From there I searched for discussions on this value and the /integritycheck option in relation to LOAD_LIBRARY_REQUIRE_SIGNED_TARGET. I found a few unofficial references that claimed the latter requires the former. So I wrote a script to dump the DLL characteristics of system DLLs in order to find one that has the IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY flag. Having found "bcrypt.dll" and checked that it wasn't already loaded, I confirmed that loading it with LOAD_LIBRARY_REQUIRE_SIGNED_TARGET does work.

Related

Debugging C: GDB returns "address where <file> has been loaded is missing"

I'm very new to the C language and have been tasked with modifying GRUB. What a way to learn, right? Anyway, I'm trying to debug my modified GRUB using VMWare and GDB. I've been able to get the debugger working before, but for some reason, every time I load up my VM and connect GDB, during the loading process of GRUB, I get:
.loadsym.gdb:1: Error in sourced command file:
The address where biosdisk.module has been loaded is missing
and I have no idea what to do about it. My first thought was, "Oh, I'll just add-symbol-file <file> and that'll fix it!" but apparently that tells GDB to forget every other symbol it loaded???? So I can't add the symbol-file and set a breakpoint.
My googling only returns one semi-relevant post that doesn't really go all that in-depth on fixing the issue.
This output may also be relevant.
info file biosdisk.module
Symbols from "H:\Workspace\GRUB\Bootloader\Trunk\grub-core\kernel.exec".
Remote serial target in gdb-specific protocol:
Debugging a target over a serial line.
While running this, GDB does not access memory from...
Local exec file:
`H:\Workspace\GRUB\Bootloader\Trunk\grub-core\kernel.exec', file type elf32-i386.
Entry point: 0x9000
0x00009000 - 0x0000e6e0 is .text
0x0000e6e0 - 0x0000f68d is .rodata
0x0000f6a0 - 0x0000fe74 is .data
0x0000fe80 - 0x000175d4 is .bss
Ended up being that my codebase wasn't the same. That is, on my Windows host, I had one copy of my code and on my Ubuntu VM was another.
Using version control solved this issue.

SHCreateItemFromParsingName return FILE_NOT_FOUND when filename specified

I try get IShellItem for a file to copy it with IFileOperation COM interface from system directory to another directory. I must use exactly IFileOperation COM interface for this purpose.
When I specify full filename - return value from SHCreateItemFromParsingName() was ERROR_FILE_NOT_FOUND, but file present in the directory. When I delete filename from path below and use only folder path - all seems good, return value is S_OK.
//...
CoInitialize(NULL);
//...
WCHAR szSourceDll[MAX_PATH * 2];
wcscpy_s(szSourceDll, MAX_PATH, L"C:\\Windows\\System32\\sysprep\\cryptbase.dll");
r = CoCreateInstance(&CLSID_FileOperation, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_HANDLER, &IID_IFileOperation, &FileOperation1);
if (r != S_OK) return;
FileOperation1->lpVtbl->SetOperationFlags(FileOperation1, FOF_NOCONFIRMATION | FOFX_NOCOPYHOOKS | FOFX_REQUIREELEVATION);
r = SHCreateItemFromParsingName(szSourceDll, NULL, &IID_IShellItem, &isrc);
//...
CoUninitialize();
//...
Why this code, written in C, not working with filenames. How can I create IShellItem instance for file in system folder to copy it?
P.S.
Windows 7 x64, C, Visual Studio 2015, v140 platform toolset, additional dependencies: Msi.lib;Wuguid.lib;ole32.lib;ntdll.lib
P.P.S
It's properly work with files in user`s directories...
Assuming your application is compiled as a 32-bit application and running on a 64-bit OS, a file not found error is probably correct because your application is redirected to the 32-bit system directory (%WinDir%\SysWoW64).
In most cases, whenever a 32-bit application attempts to access %windir%\System32, %windir%\lastgood\system32, or %windir%\regedit.exe, the access is redirected to an architecture-specific path.
For more information, see File System Redirector on MSDN.
You could temporarily turn off redirection in your thread but it is not really safe to do this when calling shell functions, only functions in kernel32. If the API you are calling internally uses LoadLibrary and/or COM then the API might fail because it will be unable to load from system32 while redirection is disabled.
You can also access the native system32 directory with the %WinDir%\SysNative backdoor. This only works in 32-bit applications on 64-bit Vista+ so you must do some version detection.

Upper filter device driver for a mouse

I've just started diving into driver related stuffs as what I want to do (cf. here) seems undoable with a "regular" application. For now, I'm just trying to install a Kernel Mode Driver (KMDF) as an upper filter for the mouse I want to modify the behaviour. The source files are not empty as they are filled in according to the Visual Studio KMDF template. The only modification I did so far in those source files was adding those two lines of code in the CreateDevice routine :
WdfFdoInitSetFilter(DeviceInit);
WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_MOUSE);
to specify that the driver is a mouse filter driver.
However, I'm having trouble to install it as I would like on my virtual machine. Here is the INF file (don't pay too much attention to the comments, I just added them to better understand what's going on as it's the first time I'm confronted to such a file):
;
; EGMC_filter.inf
;
[Version]
Signature="$WINDOWS NT$" ;Operating system for which the INF file is valid
Class=Mouse ; The class is mouse
ClassGuid={4d36e96f-e325-11ce-bfc1-08002be10318} ; Mouse class GUID
Provider=%ManufacturerName% ; is specified in the Strings section (bottom of this file)
CatalogFile=EGMC_filter.cat ; for signature
DriverVer= ; TODO: set DriverVer in stampinf property pages
; The DestinationDirs section specifies the target destination directory for all copy, delete and/or rename operations
; on files referenced by name elsewhere in the INF file
[DestinationDirs]
DefaultDestDir = 12 ; directory is \Drivers on WinNT platforms
EGMC_filter_Device_CoInstaller_CopyFiles = 11 ; Directory is \system32 on WinNt platforms
[SourceDisksNames]
1 = %DiskName%,,,""
[SourceDisksFiles]
EGMC_filter.sys = 1,,
WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames
;*****************************************
; Install Section
;*****************************************
[Manufacturer] ; This section is used to list all devices handled by the driver
%ManufacturerName%=Standard,NT$ARCH$ ;stands for architecture. Is modified depending on x64 or x86
[Standard.NT$ARCH$] ; This is a model section
%EGMC_filter.DeviceDesc%=EGMC_filter_Device, USB\VID_093A&PID_2510; Specifying the Hardware ID for which to install the driver. No revision nb specified
[EGMC_filter_Device.NT] ; This is a DDInstall section
CopyFiles=Drivers_Dir ; CopyFiles directive that specify a copyfiles section (Drivers_Dir)
AddReg=EGMC_filter.AddReg
[EGMC_filter.AddReg]
HKR,,"UpperFilters",0x0010008,"EGMC_filter" ; REG_MULTI_SZ value
[Drivers_Dir] ; This is a CopyFile section.
EGMC_filter.sys ; All the files in this section are copied to the specified directory in the DestinationDirs section.
;-------------- Service installation
[EGMC_filter_Device.NT.Services]
AddService = EGMC_filter,%SPSVCINST_ASSOCSERVICE%, EGMC_filter_Service_Inst ; create a service installation section
; -------------- EGMC_filter driver install sections
[EGMC_filter_Service_Inst]
DisplayName = %EGMC_filter.SVCDESC%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 3 ; SERVICE_DEMAND_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %12%\EGMC_filter.sys ; create a value in the registry with the fully qualified path of the driver's file
;
;--- EGMC_filter_Device Coinstaller installation ------
;
[EGMC_filter_Device.NT.CoInstallers]
AddReg=EGMC_filter_Device_CoInstaller_AddReg ;Add a registry section
CopyFiles=EGMC_filter_Device_CoInstaller_CopyFiles
[EGMC_filter_Device_CoInstaller_AddReg]
HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller"
[EGMC_filter_Device_CoInstaller_CopyFiles]
WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll
[EGMC_filter_Device.NT.Wdf]
KmdfService = EGMC_filter, EGMC_filter_wdfsect
[EGMC_filter_wdfsect]
KmdfLibraryVersion = $KMDFVERSION$
[Strings]
SPSVCINST_ASSOCSERVICE= 0x00000002
ManufacturerName="EGMC" ; My manufacturer name
ClassName="Mouse" ; ClassName of the device
DiskName = "EGMC_filter Installation Disk" ; the disk name. DON'T KNOW WHERE IT COMES FROM !!!
EGMC_filter.DeviceDesc = "EGMC Filter Device"
EGMC_filter.SVCDESC = "EGMC_filter Service"
I'm trying to install my driver in a virtual machine running Windows 10. The VM is configured to support USB 2.0 and I've added a USB device filter in order for the VM to detect my particular mouse (otherwise, the VM couldn't distinguish the different mice connected).
First I tried deploying it via Visual Studio using the "Install/Reinstall and Verify" option in the project properties (configuration properties -> Driver Install -> Deployment). Note that remove previous driver versions before deployment is selected.
It didn't work and I got the following error messages :
[17:32:01:625]: ERROR: Task "Default Driver Package Installation Task" failed to complete successfully. Look at the logs in the driver test group explorer for more details on the failure.
[17:32:02:348]: Driver Post Install Actions
[17:32:02:348]: Removing any existing files from test execution folder.
[17:32:02:375]: Copying required files for "Driver Post Install Actions".
[17:32:02:934]: [Driver Post Install Actions] Command Line:
$KitRoot$\Testing\Runtimes\TAEF\te.exe "%SystemDrive%\DriverTest\Run\DriverTestTasks.dll" /select:"#Name='DriverTestTasks::_DriverPostInstall'" /rebootStateFile:%SystemDrive%\DriverTest\Run\DriverTestReboot.xml /enableWttLogging /wttDeviceString:$LogFile:file="%SystemDrive%\DriverTest\Run\Driver_Post_Install_Actions_00011.wtl",writemode=append,encoding=unicode,nofscache=true,EnableLvl="WexStartTest|WexEndTest|WexXml|WexProperty|WexCreateContext|WexCloseContext|*" /runas:Elevated
[17:32:05:387]: Result Summary: Total=1, Passed=1, Failed=0, Blocked=0, Warned=0, Skipped=0
[17:32:05:388]: Task "Driver Post Install Actions" completed successfully
Driver Deployment Task Failed: Default Driver Package Installation Task
It may sound stupid but I was unable to locate the logs in the driver test group explorer to get more info about the error.
Secondly, I tried using the "Hardware ID Driver" option instead of the "Install/Reinstall and Verify" one with the following Hardware ID "USB\VID_093A&PID_2510" (same as the one specified in the INF). It worked this time. However, I'm not sure to understand exactly why. So now that you got a better picture of what I'm doing, here are my questions :
1) I did understand that the SourceDisksNames section is used to specify the name of a disk (CD-rom, DVD) containing the .sys file of the driver. However, I don't understand how to install a driver from such a disk practically. Imagine I buy a specific hardware and it comes with a CD with the corresponding driver files. Once the CD is in the player, what should I do ? Should I run the INF file in order to install it ? From what I remember the only time I had to install a driver from a disk it was a .exe file.
2) What if I want to release my driver package via Internet ? What's the point of this section then ?
3) By default when I created the project, VS filled the disk name with "EGMC_filter Installation Disk". What does it correspond to ? Should I modify it ?
4) I don't understand how the deployment process works. I guess that VS first transfers the driver package (containing the .INF, .cat and .sys) to the VM and then launches the .INF file in the VM. Is that right ? If yes, what does the DiskName correspond to in the VM ? Does VS create some kind of ISO containing the package ? Where can I find where the package is stored in the VM ?
5) Does the deployment process differ when using the "Hardware ID Driver Update" and the "Install/Reinstall […]" options ?
6) Any idea why I can't install my driver using the "Install/Reinstall and Verify" option ? What's wrong with the INF file ? Has it something to do with the Disk name ?
7) Despite having read this page, I'm confused about why I can deploy my driver with the "Hardware ID" option considering that I didn't respect the form Root\xxx (I saw this page afterwards). However, it seems clear that for what I want to do, I must install my driver using the other option. Any idea why it still seems to work (at least partially) ?
8) After the "incorrect" installation is completed, a "EGMC Filter Device" entry is added to the Device Manager under Mice and other pointer devices even when the mouse of interest is unplugged. Why is this ? When I plug it, another entry appears.
9) When my driver is installed, the mouse doesn't work anymore (it doesn't even light up !). However, as the upper filter doesn't do anything for now, the mouse should work normally. The only explanation I've found so far is that the driver is installed as a function driver and not as a filter one. Could it be the case ? In the registry of the VM, I'm unable to find the UpperFilters keys with the "EGMC_filter" value in the section "Ordinateur\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class{4d36e96f-e325-11ce-bfc1-08002be10318}". The only one I found is : "UpperFilters : VboxMouse mouclass". It comforts me in my idea that the driver is installed as a function one… Could the VM interferes with my driver ?
10) The driver details of the mouse of interest (left) and the regular one (right) also confuse me as the mouhid is missing from the former.
11) Lastly, what's the point of specifying in the driver code that it's a filter driver ? What does it change concretely ?
I know it's a long post and that I'm asking quite specific questions but I hope you won't mind and hopefully some experts right there will be able to answer them.
I'm looking forward to your replies.
Guillaume.

Can't Find "Syslog.conf" in linux kernal 2.6.37.6 created with BuysBox v1.19.3

I created a tiny OS for my controller with Linux kernel 2.6.37.6 with the help of BusyBox and tool chain. I am writing a logging module(C program) in it and i want customized logs(customized path for different logs) like in /log/.
I have syslogd in my machine and /etc/syslog.conf supposed to present in my machine but it's not it the place. I created new syslog.conf under /etc but still i can't find my logs in desired place.
But if i run command syslogd -O /log/Controller.log all logs started to redirect to this (specified file). So i want to know where is the configuration file for this syslogd i can't find the configuration file for it.
Is there any way that i can write a module(program) for LOGS without requiring syslog.conf and yes of course traditional printf way. Problem is that for customized paths for log we need to give keyname LOG_LOCAL1 in openlog() as a argument but it's not working
I followed procedure from this examples http://www.codealias.info/technotes/syslog_simple_example
If you are using Busybox's syslogd then there is no support of syslog.conf,all logs are written to /var/log/messages by default.
You can modify code of syslogd in busybox which is located in busybox/sysklogd/syslogd.c for your desire behaviour
You can change code of syslogd like this
static const struct init_globals init_data = {
.logFile = {
.path = "your desire path",
.fd = -1,
},

How to determine called kernel32.dll function from fault offset

I have an app running as a Windows Service. Today, I was notified that the service died. I found a event viewer entry whose basic info is: faulting module kernel32.dll, version 6.0.6002.18740, time stamp 0x50b58c3d, exception code 0xc0000005, fault offset 0x0003fc2e
I'm sure that there is a bug in my code. Can I determine the kernel32.dll function (where the exception came from) from the offset? I'm planning to backtrack to the call in my code.
I agree with what is said in the comments, but anyway I think the answer can be useful. Here is how you can find function name using Windows debugging tools from SDK provided that EventViewer reported offset of failing instruction in kernel32.dll.
First, install Windows debugging tools and configure path to Microsoft public symbol server. Instructions are available online, for example, this video: http://channel9.msdn.com/Shows/Defrag-Tools/Defrag-Tools-Building-your-USB-thumbdrive
Start windows debugger attached to your process or just any process in the system. kernel32.dll is one of the first DLLs any process loads, it is very unlikely that it is rebased. So kernel32.dll’s base address is the same in all processes.
Get base address of kernel32.dll by running “list modules” command in debugger
0:006> lm m kernel32
start end module name
7c800000 7c8f6000 kernel32 (pdb symbols) c:\debuggers\symbols\kernel32.pdb\A22E3A9843CC45B4A2BFA31377127D422\kernel32.pdb
So the base address is 7c800000. Now run “disassemble single instruction” command using DLL base address and offset:
0:006> u 0x7c800000+0x0003fc2e l 1
kernel32!BasepCopyFileExW+0x859:
7c83fc2e 53 push ebx
So BasepCopyFileExW is the function name. (The result on your system may be different.)

Resources