I tried loading the DLL file "bcryptprimitives.dll" (which in my case, originally sits under "C:\Windows\syswow64\bcryptprimitives.dll") from another location, with this snippet of code:
LoadLibraryW(L"<altered path>\\bcryptprimitives.dll");
However, right after executing this line of code I get the following error:
C:\Program Files (x86)\Notepad++\bcryptprimitives.dll is either not designed to run on Windows or it contains an error. Try installing the program again using the original installation media or contact your system administrator or the software vendor for support. Error status 0xc0000428.
I searched the 0xc0000428 NTSTATUS in the following dictionary: https://msdn.microsoft.com/en-us/library/cc704588.aspx
and apparently this status means STATUS_INVALID_IMAGE_HASH.
The error at first makes sense, because I changed the "LoaderFlags" field in the image PE header from 0x00000000 to 0x00000001 (which doesn't need to affect anything because this field is deprecated), but even though I changed the field, I fixed the PE checksum.
As you can see:
However, LoadLibrary still refuses to load the DLL.
Diving deep into ntdll reveals that the error is returned from kernel:
It makes me think that the DLL is somehow signed and the kernel checks whether the DLL was altered.
So to my point, how can I load this DLL from another location anyway and remove the sign check?
If a DLL is signed, then by changing a single byte in the file will invalidate the signature. It appears you are doing exactly that by modifying PE header.
This blog post might be of interest to for deeper insight how this technology works:
Code Integrity is a feature that improves the security of the operating system by validating the integrity of a driver or system file each time it is loaded into memory. Code Integrity detects whether an unsigned driver or system file is being loaded into the kernel, or whether a system file has been modified by malicious software that is being run by a user account with administrative permissions. On x64-based versions of the operating system, kernel-mode drivers must be digitally signed.
Found a quick solution:
DWORD dwIndex = 0;
hFile = CreateFileW(L"C:\\Program Files (x86)\\Notepad++\\bcryptprimitives.dll", FILE_READ_DATA | FILE_WRITE_DATA, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
while (ImageRemoveCertificate(hFile, dwIndex))
{
++dwIndex;
}
LoadLibraryW(L"C:\\Program Files (x86)\\Notepad++\\bcryptprimitives.dll");
It is working like a charm :)
This is how the API works:
Calculate the offset of the end of the last section.
Remove all the data following that section.
Remove the security data directory.
Shrink the image.
Calculate an updated checksum of the PE.
Related
HINSTANCE hinstLib=LoadLibrary("C:\\mydll.dll");
I have no idea why I always get 0 in return after running that line of code.
Actually I have also another COM dll namely mydllCOM.dll that I already registered successfully with regsvr32 command. I would like to use the above (mydll.dll) in my application but always fail at the line as mentioned.
The error code I got from GetLastError is 193 and I have no idea, why it is about the wrong type of dll
The error code looks like it has the "wrong bitness", meaning you're probably mixing 32-bit and 64-bit executables/DLLs. The setting in the Project properties "Linker->Advanced->Target Machine" should be set to the same value in your DLL and in the executable loading that DLL.
I had a similar problem but with a dll that wasn't mine.
The solution was to change the Character set(i.e. Project properties->configuration Properties->general->Character set).
The default was unicode and when I changed it to multi-Byte i managed to load the dll.
You can't load 32bit DLLs into 64bit applications and vice versa.
You need to recompile your Application and Dll with the same Linker->Advanced->Target Machine setting.
I am trying to open a couple different files via their absolute path (determined elsewhere, programmatically), so I can get their SHA1 hash*, some of which are core windows files. fopen() is returning NULL on some (but not all) files when I attempt to open them as follows (normally the filename is gotten via QueryFullProcessImageName but I hardcoded it just in case):
char * filename = "c:\\windows\\system32\\spoolsv.exe";
FILE * currFileRead = fopen(filename, "rb");
if (currFileRead == NULL)
{
printf("Failed to open %s, error %s\n", filename, strerror(errno) );
}
else
{
//hashing code
}
The reported error is 2: "No such file or directory", but obviously they're there. It also only fails for some processes, like spoolsv.exe or winlogon.exe, while svchost.exe and wininint.exe seem to open just fine.
My program has administrative privileges, and I can't figure why some processes would fail while others opened without trouble?
*I'm using a method from LibTomCrypt (http://libtom.org/?page=features) which is open source with a permissive license. The call to sha1_process takes in a hash_state (internal to the library), an unsigned char buffer, and the length of the buffer. I need to read the file with fopen to get the file into memory for hashing.
Because your program is a 32-bit process, when you try to open c:\windows\system32 you actually get c:\windows\syswow64 which does not contain all of the same files.
You can use IsWow64Process to determine whether you are running on a 64-bit system. If you are, you can replace system32 with sysnative in the path to open the actual file, unless you need to support Windows 2003 or Windows XP. Depending on your circumstances, you might need to cope with the possibility that the Windows folder is not c:\windows and/or the possibility that there are other folders named system32.
On the whole it would be more robust to have separate 32-bit and 64-bit versions of your application, or perhaps just the particular part of it that is exhibiting the problem. If you can't leave it up to the user to install the appropriate version, the installer could decide which to install, or you could always install both and have the 32-bit version automatically launch the 64-bit version when running on a 64-bit system.
Having administrative privileges is not always enough, because if the file you want to open is in use and the program that is using it has locked it, then you can't open and read that file.
I am trying to understand the different file extensions for the pfxplus powerflex database. Could someone please help telling me briefly what each file is for?
.k1
.k2
.k3
...
.k13
.k14
.k15
.fd
.def
.hdr
.prc
.pc3
Data files:
OK, so .dat is the data file.
.k1 -> .k15 are index files.
These are the critical data files for runtime. (Combined with filelist.cfg or pffiles.tab similar to define what files are available overall).
.fd is the file definition, needed for compiling programs
.tag (which you did not mention) is needed only if you need to access field names at run time (such as using a generic report tool)
.def is the file definition in human readable form, and is not needed by any process but is produced so a programmer or user can understand the file structure.
Run time:
The .ptc files are the compiled threads interpreted by the powerflex runtime.
The .prc file is a resource file that is used at runtime in conjunction with the .ptc file - it defines how a character based program is to look in a gui environment in "g-mode". It was the cheap way to upgrade character based programs when windows first started getting popular usage.
.hdr and .pc3 escape me at the moment, but are vaguely familiar - .hdr is probably another data file used with compression or special field types for later versions of pfxplus. .pc3 may in fact be the .ptc files...
I am making a filtering sniffer in C and winPCAP that starts on every boot. For this I want to make a self-contained exe file that extracts (no, not compression!) the exe and DLLs to a new folder and performs other commands (like modify startup settings) silently, without showing any window/terminal.
So
The single file contains an exe and DLLs.
When executed, it copies the files to a folder and does other commands
It does it silently, without any windows or terminals or user intervention
I stress on the silent part, so I cant choose some easy installers. Can you reccomend something that generates this executable?
For the curious: its a stealth packet logger program for my college project. The "stealth" part will be tried out only on xp2 virtual machines with IE6 (yeah, old stuff).
EDIT: answering the commenters: it is of a malware character. So I am running it in virtualbox, never on the loose. And I can compromise only an unpatched xp systems with IE6, without antivirus, that is from an OLD install disk. Thats the scope of the IE css use after free vulnerability, AFAIK never seen in the wild. So there is no unethical behavior involved.
You can easily embed resources either by linking them in, with the compiler, or by using a special program and instrumenting the windows API.
Something along the lines of :
char file_to_be_altered[] = "MyInstaller.exe"
HANDLE hUpdate = BeginUpdateResource( file_to_be_altered, FALSE );
UpdateResource( hUpdate, "MyResType", "MyResName1", 0, pData, data_len );
EndUpdateResource( hUpdate, FALSE );
Then when your executable runs, you enumerate your resources and select those that have the type "MyResType".
struct res_entry { BYTE* pData; unsigned int len; }
BOOL CALLBACK EnumNamesCB(
HMODULE hModule, // module handle
LPCTSTR lpType, // address of resource type
LPTSTR lpName, // address of resource name
LONG_PTR lParam) //
{
std::vector<res_entry>& lst = *(reinterpret_cast< std::vector<res_entry>* >( lParam ));
HRSRC hRes = FindResource( hModule, lpName, lpType );
if( hRes == 0 ) return TRUE;
unsigned int len = SizeofResource( hModule, hRes );
HGLOBAL hGlob = LoadResource( hModule, hRes );
if( hGlob == 0 ) return TRUE;
res_entry t;
t.pData = LockResource( hGlob );
t.len = len;
lst.push_back( t ); // this is safe, because the resources are never deallocated
return TRUE;
}
....
void enum_entries()
{
std::vector<res_entry> lst;
::EnumResourceNames( hFileToQuery, "MyResType", &EnumNamesCB, reinterpret_cast<LONG_PTR>(&lst) );
}
You can do whatever you want with this data, e.g. CreateFile ... and the write the data out to disc.
NB: This is how installers may do it on windows, and this was developed to extract files to the temp dir and install from there.
The trivial way to do it is to create a very large array inside your program, and store the data to be extracted inside that array. When executed the program takes the array and writes it out to a file or files as needed, then executes the file you want to run once the files are extracted. See, for example, C Question: How to store data inside the executable file.
Once the program is compiled you can replace the data in the EXE using a binary editor to copy your files in place without having to convert your files to a C array or some other data structure every time you change your payload.
In order to keep the size down the primary program typically decompresses the array and expects a compressed array. A lot of installers simply use zip as the decompressor takes care of multiple files in one array, and you don't have to fiddle with adding a directory array and reference array - it's all built in, and command line zip compressors are common and easy to use.
Whether the primary program opens a terminal depends on how you program it. I expect you'll need it to be a win32 program so windows doesn't open a DOS terminal, and you simply don't open any windows inside your program. That's a separate question, though, so consider asking it as a new question.
As David points out, this process is typically automated in the linker stage. Each linker is slightly different, but you can check out Embedding resources in .exe using GCC for an example using one of the more common compilers.
I assume you know what you are doing, but keep in mind that there are a lot of unpatched stock winxp sp2 systems out there - assuming that you won't hurt anyone because you don't believe such systems are online is a poor choice. Make certain that your program doesn't have the ability to leave the virtual machines. There are ways, for instance to connect their networks without allowing the machines access to the internet, or your computer's network. Keep in mind that the Morris worm was a pet project that wasn't intended or expected to go wild either.
I'm trying to call SymLoadModuleEx to load the symbols from a PDB file and then use SymFromAddr to look up symbols from that PDB. However, I can't figure out what to pass for the parameters BaseOfDll and DllSize -- the documentation explicitly says that when loading a PDB file, these parameters can't be 0, and indeed attempting to pass 0 results in it failing with ERROR_INVALID_PARAMETER.
Here's what my code looks like:
SymSetOptions(SYMOPT_LOAD_LINES);
HANDLE hprocess = GetCurrentProcess();
if (!SymInitialize(hprocess, NULL, FALSE))
die("SymInitialize");
if(SymLoadModuleEx(hprocess, NULL, "full path to some PDB file.pdb", NULL,
0, // What to pass here?
0, // What to pass here?
NULL, 0) == 0)
{
die("SymLoadModuleEx");
}
How do you figure out what BaseOfDll and DllSize to pass in when loading a PDB file? The PDB file in question is the symbol file for a different program executable (not a DLL), and just for the sake of argument, assume that you don't have access to the original EXE from which the PDB was generated.
Alternatively, is there a better method of looking up the symbols corresponding to a given address from a PDB file?
dbghelp.dll and the Sym* methods here make use of the Debug Interface Access (DIA) SDK.1
DIA itself is COM-based and much more flexible than what DbgHelp offers.
Specifically, to load a known PDB and lookup a symbol based on an address, you can do the following:
CoCreate a DIA data source (see the "Example" section here).
Use IDiaDataSource::loadDataFromPdb to load a specific PDB (DLL size and base address are not needed).
Use IDiaDataSource::openSession to get the IDiaSession for your data source.
Depending on if you have an absolute virtual address (VA) or relative virtual address (RVA), you can use findSymbolByVA or findSymbolByRVA, respectively, to get the IDiaSymbol associated with that address.
Finally, you can use IDiaSymbol::get_name to get the function name containing the address you specified.
None of this requires the original image; only the PDB is required. Assuming you're using Visual Studio, the headers and libraries for DIA are available under (for example):
C:\Program Files (x86)\Microsoft Visual Studio 10.0\DIA SDK.
The Dia2Dump sample works well for me in resolving relative virtual address (eip-program load address) to pdb for unresolved function pointers. This is the way I try it:
DWORD64 dwAddress = _wcstoui64(argv[i], NULL, 16);
DWORD64 dwRVA = dwAddress - dwLoadAddress;
long displacement = 0;
IDiaSymbol* pFunc = 0;
error = (DWORD)g_pDiaSession->findSymbolByRVAEx(dwRVA, SymTagFunction, &pFunc, &displacement );
if (!error && pFunc)
{
BSTR bstrName;
if (pFunc->get_name(&bstrName) != S_OK) {
wprintf(L"(???)\n\n");
}
else {
wprintf(L"%s \n\n", bstrName);
if (displacement)
wprintf(L"+ 0x%x \n\n", displacement);
else
wprintf(L" \n\n");
SysFreeString(bstrName);
}
}
For example:
Function: [00447B60][0001:00446B60] ServerConfig::getSSLConfig(public: struct ssl_config __cdecl ServerConfig::getSSLConfig(void) __ptr64)
Here the RVA is 00447B60 [ eip - Process Load Address ]
the Segment is 0001
the offset is 00446B60
I don't have permitions to comment, so will do this in separate answer.
Yes, DbgHelp is a wrapper around DIA, only in terms of static lib. DIA is statically linked into DbgHelp.dll. DbgHelp directly calls Dia's COM class factory (IClassFactory) implementation bypassing COM. I'm talking about 6.1.7601.17514 version. So DbgHelp.dll is self-contained (in combination with symcrv.dll and srcsrv.dll)
Dia COM objects are shipped with Visual Studio (same location with dbgeng.dll), so solution we not work on envs where VS is not installed (but you still could try to use msdia120.dll as private assembly pointing to it via ActivateActCtx, but also need to deploy dependencies, if they present)
DbgHelp is compact and recommended to distribute private copies with your application by Microsoft. See "The redistribution policies for these included DLLs were specifically designed to make it as easy as possible for people to include these files in their own packages and release"
I didn't find the way how to download PDB files using DIA interfaces. Sym API allows this. it delegates calls to SymSrv.dll.
So original question is still actual.