can a virus interrupt a dll function calls - windows

I have a 32 bits executable that calls functions inside a Dll file. When installed, the dll is copied in the same folder of the executable and the system directory (system32 on 32 bit platform and sysWOW64 on 64 bits platforms). I've sucessfully tested this executable on:
a Pc with winXP 32 bits,
a Virtual Machine with Win7 32 bits,
two PCs with win7 64 bits,
a laptop with win8 64 bits.
Then a customer gave me a laptop with Win 7 64 bits. It is infected with a virus (those kind of virus that hide all your folders and files in your memory stick and create shorcuts). On this laptop, my executable is unable to find my dll despite it is copied in the respective folders. My exe shows an error message that says "Unable to find mydll.dll".
Is it possible that the virus is interrupting the calls to the dll and messing up with my executable?

Yes, a virus can hook into ("override") LoadLibrary or GetProcAddress and just return a null value.
Then you'll receive this message.
Or it can put itselfs into the dll-loading process (infection) and cause a failure by an unintended malfunction.
It can remove execution permission
Or it can override the dll's magic bytes, so the system does no longer recognize the dll as dll...
Or it can "override" the file listing API, and always return null...
Or it can also recursively load/call itselfs until a stackoverflow occurs (it can also do this with a time-delay, causing seemingly random crashes)
or... or... or...

Generally speaking, it's a bad idea to do any testing whatsoever on a machine you know to be infected with a virus. Certainly one that is obviously mucking with the entire system. You literally cannot trust any single thing being said by the system because it is compromised.
So, really this has nothing to do with whether or not your DLL can be seen, bla bla bla... You should be concentrating on wiping the drive on that machine and starting over.
And while you're at it, don't put that thumb drive into another machine. Put it on a Linux box and format it. (virus can't spread that way.)

Related

SDL.dll missing on Windows 10 even though it's in the game folder

I've deployed many games over the years on Windows and always shipped the necessary SDL.dll along with the game, in the game's folder.
This has always worked fine, and continues to work for well over 99% of people.
However, I'm starting to see reports of "The code execution cannot continue because SDL.dll was not found" from a few users. They all seem to be on Windows 10. And they confirm that the DLL is indeed in the game folder as it should be, and they're running the game directly from inside the folder, and not through a shortcut that would break the working directory.
I also have reports from other Windows 10 users who are not having this problem.
I did some research and found that this kind of error can be misleading, and may be triggered if the DLL itself loads another system DLL that is not found.
I used DependencyWalker on my EXE and found the SDL.dll depends on:
ADVAPI32.DLL
GDI32.DLL
KERNEL32.DLL
NTDL.DLL
MSVCRT.DLL
USER32.DLL
WINMM.DLL
Those all seem pretty standard. Would they be missing from certain Windows 10 installs for some reason?
Other ideas is that Windows 10 is moving to a signed DLL requirement (just a guess) or that the way Windows 10 handles library load paths has changed.
But again, this is working for other people on Windows 10.
Other details: DLL and EXE are both 32-bit. The systems in question are most likely 64-bit.
In this case, it turns out to be a really stupid end-user mistake.
I'm answering it here just in case anyone else runs into it.
When a user double-clicks a ZIP file, it LOOKS like they've opened a folder and are viewing the files.
They can even run the game from inside this ZIP browsing view.
But of course, Windows can't find DLLs that are also inside the ZIP file.
Thus, this behavior on Windows is pretty confusing to end users. The solution is to extract the ZIP first before running the game.

Is my 32 bit & 64 bit installers in the wrong directories?

I'm having trouble installing a 64 bit program on my windows PC.
I'm running windows 7 64 bit.
Looking in regedit after a bit of googling I noticed the files seem to be in the opposite directories to what I think they should be.
Nope, those look correct to me. They are indeed confusing at first, and can be difficult to talk about.
System32 is the native system directory, and happens to be misleadingly named on a 64-bit system.
SysWow64 indicates the system directory for the Windows (32)-on-Windows 64.
Note of course that only a 64-bit application, or one that has disabled redirection, can use a path containing "System32" to reach the 64-bit files it contains.

ASLR and Windows System DLLs for non-aware executables?

From a Microsoft article:
Address Space Layout Randomization (ASLR)
ASLR moves executable images into random locations when a system
boots, making it harder for exploit
code to operate predictably. For a
component to support ASLR, all
components that it loads must also
support ASLR. For example, if A.exe
consumes B.dll and C.dll, all three
must support ASLR. By default, Windows
Vista and later will randomize system
DLLs and EXEs, but DLLs and EXEs
created by ISVs must opt in to support
ASLR using the /DYNAMICBASE linker
option.
I don't quite get it. Take the base system DLLs loaded by every process on WIndows: NtDll.dll and kernel32.dll.
If a have a non-aware executable, will these system DLLs use ASLR? That is, will they load at a different base address after every system reboot on Win 7 for this executable or will they always load at the same base address after system reboot like they do on Win XP?
To make it more clear what I mean: My typical dummy program's startup stack will look like this:
write_cons.exe!wmain() Line 8 C++
write_cons.exe!__tmainCRTStartup() Line 583 + 0x19 bytes C
write_cons.exe!wmainCRTStartup() Line 403 C
> kernel32.dll!_BaseProcessStart#4() + 0x23 bytes
Looking at the asm of BaseProcessStart, I see on my XP box here:
_BaseProcessStart#4:
7C817054 push 0Ch
7C817056 push 7C817080h
7C81705B call __SEH_prolog (7C8024D6h)
7C817060 and dword ptr [ebp-4],0
...
Now what interests me is the following:
On Windows XP, the address will always be 0x7C817054, regardless of how many times I reboot this machine. If I were on Win7 with ASLR, will this address change between reboots if the executable that loads kernel32.dll is not enabled for ASLR?
(Note: For me, atm., there is only one minor use-case this address would be useful for: In Visual Studio, I can only set a "Data Breakpoint" for assembly level functions, that is a breakpoint # 0x7... - If I want to break in a specific ntdll.dll or kernel32.dll function, in Windows XP I do not have to adjust my breakpoints between reboots. With ASLR kicking in (the scope of this question) I would have to change the Data Breakpoints between reboots.)
Technically whether the system dlls get relocated or not, it shouldn't matter, as the linker will bind to symbols, not addresses. These symbols are resolved by the runtime loader into to addresses for the instanced system dlls, thus your binary should be none the wiser. From what i've seen however, windows 7 will reset the base randomization every reboot, including system dlls(note: this is from debuging WOW64 apps on widows server 2008 R2). You can also do a system wide disabling of ASLR via some registery edits, but thats not really relevant...
Update:
the section on ASLR in this article explains what gets relocated and when.
it doesn't mention if the base will reset every reboot, but for system dlls, its never going to be guaranteed to load at the same address twice, reboot or no reboot.
the important thing is according to article, everything needs to opt-in to ASLR for system dll's to be relocated.
Your program will resolve calls into system DLLs wherever they happen to be loaded. But, unless your executable is linked with /DYNAMICBASE, it will not be given a randomized base address. In other words, your exe will always load at the same base address.
If you want your exe to load at a randomized address, then you have to link it with /DYNAMICBASE, and every DLL that it references must also have been linked with /DYANMICBASE. The system DLLs (starting in Vista) are all linked with /DYNAMICBASE.

How should my program decide to install under "Program Files (x86)"?

Just out of curiosity, if I am creating a program installer, how should I decide in which "Program Files" directory to install to? On 32-bit systems, the environmental variable "%programfiles%" is good enough. However, on 64-bit systems, 32-bit programs should not install to that folder and instead to "%programfiles(x86)%", which as I understand points to "C:\Program Files (x86)". My question is: How should the installer decide which environment variable to use? Will the value of "%programfiles%" change for a 32-bit application, or should I always check first whether "%programfiles(x86)%" exists before using "%programfiles%", or should I do something entirely different?
Thanks! This is just out of my own curiosity, as I try to get used to 64-bit operating systems.
When the 32-bit program (installer in your case) asks the system to resolve the ProgramFilePath constant (check the exact name in MSDN), the system does not return C:\Program files, but C:\Program files(x86). So it's the system that decides, not the application.
I'm pretty certain that I read somewhere that Windows did this for you automagically. In other words, if your installer was 32-bits, it would be routed to the x86 directory variant even though you were trying to install into Program Files.
I'm sure I read this on The Old New Thing but here's a link that supports the contention until I can find that one.
Ah, yes, here it is, from the ever useful Raymond Chen.
Commenter Koro is writing an installer in the form of a 32-bit program that detects that it's running on a 64-bit system and wants to copy files (and presumably set registry entries and do other installery things) into the 64-bit directories, but the emulation layer redirects the operations into the 32-bit locations. The question is "What is the way of finding the x64 Program Files directory from a 32-bit application?"
The answer is "It is better to work with the system than against it." If you're a 32-bit program, then you're going to be fighting against the emulator each time you try to interact with the outside world. Instead, just recompile your installer as a 64-bit program. Have the 32-bit installer detect that it's running on a 64-bit system and launch the 64-bit installer instead. The 64-bit installer will not run in the 32-bit emulation layer, so when it tries to copy a file or update a registry key, it will see the real 64-bit file system and the real 64-bit registry.

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.

Resources