I tried to make self-updatable program, but I can't understand, how to over-write exe file of the running program (of the current process). When Exe file is running, it's locked by process and can't be writable.
How to update program - I need to update file, close current process and re-run updated file...
Maybe my question is silly, but I haven't this problem, until I used Linux...
Cheers! ❤
I solved this question by packing needed file into the another one wrapper via Resources in MS VS.
Here is code to extract resource into the file:
#include "stdafx.h"
#include "resource.h"
#include "windows.h"
int main()
{
HRSRC hrsrc = FindResource(NULL, MAKEINTRESOURCE(IDR_BINARYTYPE1), _T("BINARYTYPE"));
//FindResource(NULL, MAKEINTRESOURCE(IDR_BINARYTYPE1), RT_BITMAP);
HGLOBAL hLoaded = LoadResource(NULL, hrsrc);
LPVOID lpLock = LockResource(hLoaded);
DWORD dwSize = SizeofResource(NULL, hrsrc);
HANDLE hFile = CreateFile(TEXT("c:/temp/zxcv.exe"), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD dwByteWritten;
WriteFile(hFile, lpLock, dwSize, &dwByteWritten, NULL);
CloseHandle(hFile);
FreeResource(hLoaded);
return 0;
}
I am not realized it by 100%, but I have plan to pack my exe into the wrapper, that will unpack my exe into the %Temp% directory and will start unpacked exe file. Unpacked file will be deleted with DELETE_ON_CLOSE.
It's just plan, but I see possible solution :).
Thanks to all!
Related
I'm new to the windows services and visual studio. I am trying to start a .exe file from a wind32 application. The code works fine and there is no error. I am using a CreateProcess() method and checked whether the method is running properly. There is no issues in it. The .exe file which i am calling simply creates text document. When i call that .exe file from console, it works fine, it creates the file. But when I call it from the wind32 app, it does not create any file. I am using Visual studio 2019. This is my code for calling the .exe file. `
STARTUPINFO info;
PROCESS_INFORMATION processInfo;
ZeroMemory(&info, sizeof(info));
info.cb = sizeof(info);
ZeroMemory(&processInfo, sizeof(processInfo));
LPCWSTR path = L"C:\\HP\\...(pathofexe).exe";
bool bSuccess = CreateProcess(path, NULL, NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo);
if (bSuccess)
{
cout << "Success";
}
else
{
cout << "Error : " << GetLastError() << endl;
}`
Rgarding the working directory mismatch that was discussed in the comments, The file may not be there because it's simply somewhere else.
You call:
CreateProcess(path, NULL, NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo);
Assuming you've read the documentation, you know the 8th parameter specifies the directory where the new process will run. Because you use NULL, this directory will be the same as that of the caller process, I assume "C:\\Users\\HP\\source\\repos\\ThisThingsName\\Debug\\".
That alone is not a problem, but given the context I believe the callee (SampleService.exe) calls the file function from its relative path, "\\Success.txt", rather than the full path, is that right?
In that case, when you open SampleService.exe manually, Success.txt would appear in "C:\\Users\\HP\\source\\repos\\SampleService\\Debug\\". However, when you open it using CreateProcess, it runs in "C:\\Users\\HP\\source\\repos\\ThisThingsName\\Debug\\" (because you did not specify otherwise), which is also where Success.txt would appear.
As I type this, I'm starting to doubt it, actually. Haven't you checked where it appears in Explorer?
I am trying to learn some manual dll injection, but cant seem to get the execution of the dlls code to work. I am new to Windows C++ so any tips on improving my code is appreciated. I have also only posted the relevant code.
Injector program:
hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, getPID(TARGET_NAME));
DWORD gotDLL = GetFullPathName(DLL_NAME, MAX_PATH, dllPath, NULL);
hFile = CreateFile(dllPath, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
dllFileSize = GetFileSize(hFile, NULL);
memAddrForDLL = VirtualAllocEx(hProcess, NULL, dllFileSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
loadedDLL = HeapAlloc(GetProcessHeap(), NULL, dllFileSize);
// Load dll into allocated memory in current process
ReadFile(hFile, loadedDLL, dllFileSize, &bytesRead, NULL))
// Find offset of dll entry point
IMAGE_NT_HEADERS* pOldNtHeader = reinterpret_cast<IMAGE_NT_HEADERS*>(reinterpret_cast<BYTE*>(loadedDLL) + reinterpret_cast<IMAGE_DOS_HEADER*>(loadedDLL)->e_lfanew);
IMAGE_OPTIONAL_HEADER* pOldOptHeader = &pOldNtHeader->OptionalHeader;
entryPointOffset = pOldOptHeader->AddressOfEntryPoint;
// Load dll into allocated memory in target process
WriteProcessMemory(hProcess, memAddrForDLL, loadedDLL, bytesRead, NULL)
LPTHREAD_START_ROUTINE entryPoint = (LPTHREAD_START_ROUTINE)((unsigned __int64)memAddrForDLL + entryPointOffset);
CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibrary, entryPoint, NULL, NULL)
DLL:
DWORD WINAPI OnDllAttach(LPVOID base){
typedef void func(void);
func* f = (func*)0x00007FF605EC5835;
f();
FreeLibraryAndExitThread(static_cast<HMODULE>(base),1);
}
BOOL WINAPI OnDllDetach(){
return TRUE;
}
BOOL WINAPI DllMain(_In_ HINSTANCE hinstDll,
_In_ DWORD fdwReason,
_In_opt_ LPVOID lpvReserved){
typedef void func(void);
func* f = (func*)0x00007FF605EC5835;
f();
switch(fdwReason) {
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hinstDll);
CreateThread(nullptr, 0, OnDllAttach, hinstDll, 0, nullptr);
return TRUE;
case DLL_PROCESS_DETACH:
if(lpvReserved == nullptr)
return OnDllDetach();
return TRUE;
default:
return TRUE;
}
}
Target program contains this function:
void printer(){
cout << "test" << endl;
}
My injector produces the following output
1. Attempting to attatch to process target.exe
--- Got target.exe PID: 14640
--- Got target.exe Handle: 0x0000000000000084
2. Attempting to allocate memory
--- Found dll: D:\projects\injector\hack.dll
--- Got hack.dll Handle: 0x0000000000000088
--- Allocated memory in target.exe at 0x0000017BEB690000
3. Attempting to copy dll to target.exe
--- Allocated memory at 0x00000226A060FFE0
--- Loaded hack.dll in current process at 0x00000226A060FFE0
--- hack.dll is a valid DLL
--- Loaded hack.dll into target.exe at 0x0000017BEB690000
4. Attempting to execute dll
--- Offset from start of file to entrypoint: 0x3cf6
--- Began execution of hack.dll in target.exe at 0x0000017BEB693CF6
Using Ghidra I can confirm this is the correct offset for the dll entrypoint. But when running my injector nothing happens in the target process, I've also tried using cout to print a message from the dll but I get nothing(I dont think it would even work because nothing has been relocated)
I was using
CreateRemoteThread(hProcess, NULL, NULL, entryPoint, memAddrForDLL, NULL, NULL)
before as the 4th parameter is called lpStartAddress and I thought this should want the entry point but it was causing the target process to crash and every example I saw used the way I currently have it in my code.
In my dll I am calling the function in the target process by the address.
EDIT: I am testing this on my own console application.
The most basic form of DLL injection is:
Allocating Memory in target process using VirtualAllocEx()
Writing the path of the DLL to that memory location with WriteProcessMemory
Calling LoadLibrary() via CreateRemoteThread() in the target process
Passing the memory location where the DLL path is written to that call
You already have this but, your goal is to manually map the DLL and avoid using LoadLibrary(). The code you have provided is not going to work out, there are about 5 more steps. You need to emulate everything that LoadLibrary() normally does:
Load raw binary data
Map sections into target process
Inject loader shellcode
Do relocations
Fix imports
Execute TLS callbacks
Call DllMain
Cleanup
The benefits of manually mapping are that you will be hidden from ToolHelp32Snapshot(), walking the module linked list in the PEB and NtQueryVirtualMemory.
If you want to do it right, with decent error checking, it's about 350 lines of code and it gets complicated. It's all done by parsing the PE header.
Get the process id of the target
Read the DLL file
Allocate memory in target process the same size as ImageBase from the PE header
Loop through PE sections after parsing the PE header
Write the section to memory in the correct relative address
Write shellcode into target process
Call CreateRemoteThread and set your shellcode to execute
Your shellcode fixes imports and does relocations
Your Shellcode Execute TLS callbacks
The above 2 steps are done parsing the DataDirectory in the optional header
Call DllMain(), with DLL_PROCESS_ATTACH argument
Now your DLL is loaded and the DLL_PROCESS_ATTACH switch case is executing. Obivously it's more complicated than that, but that's the idea.
I wouldn't know anything about this without my friend Broihon teaching me it, so I want credit this answer to him. Good luck
A .DLL loaded in memory is not the same thing as a .DLL file on disk. The section layout is not the same and you need to deal with relocations, the import table and the PEB loaded module list. You basically have to re-implement NTDLL!Ldr*.
Calling CreateRemoteThread on LoadLibrary is a different technique and when you do this the thread parameter needs to point to the .DLLs path in the remote process, not the entrypoint.
As the topic's description/title puts it, is this a possibility because I've been searching around on Google and other sources and without any luck I've come here to ask the question...
Is it at all possible to Embed a DLL as a resource into my final Executable and then call upon it/ as-if it were an external file in the current directory and/or System Directory?
I've tried a number of things without luck, a number of said solutions are not working out so well, I've seemingly embedded the DLL with my .rc file, however am struck with the problem of trying to call upon it, perhaps it's needing to be saved into a physical file on the disk, I'm not sure.
[EDIT]
Below is currently the code I've implemented, still without any success; I am still confronted with The program can't start because soandso.dll is missing from your computer.
Code below, -/
int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
HRSRC hRes = FindResource( hInstance, MAKEINTRESOURCE("#101"), "IDR_DLLRESOURCE_101" );
HGLOBAL hData = LoadResource( hInstance, hRes );
LPVOID lpFile = LockResource( hData );
DWORD dwSize = SizeofResource( hInstance, hRes );
HANDLE hFile = CreateFile("soandso.dll", GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
HANDLE hFilemap = CreateFileMapping(hFile, 0, PAGE_READWRITE, 0, dwSize, 0);
LPVOID lpBaseAddr = MapViewOfFile(hFilemap, FILE_MAP_WRITE, 0, 0, 0);
CopyMemory(lpBaseAddr, lpFile, dwSize);
UnmapViewOfFile(lpBaseAddr);
CloseHandle(hFilemap);
CloseHandle(hFile);
return 0;
}
Thank you in advance for any and all help provided.
It is fundamentally incompatible with the way Windows treats executable code in a PE32 file format. It must be present in a file, Windows creates a memory-mapped file to map it into memory. Trying anything like loading it into memory from a resource requires you taking over all of the duties of the Windows loader. Which includes relocating the code if it cannot be located at the expected base address, finding and loading all of the dependent DLLs and calling their DllMain() methods.
Particularly the DLL_THREAD_ATTACH and DETACH notifications are next to impossible to implement yourself since you can't control every thread that gets created. Very hard to do right and there's not a single winapi that will help you doing this. It is not worth it. And most certainly not competitive with just linking the DLL's code into your EXE image.
The only supported way to load a DLL is from a file. So, when you need to load this DLL, extract the resource, save it to a file (e.g. in the temporary directory), and call LoadLibrary and GetProcAddress to link to the library.
I have two separate executable files, A.exe & B.dontrun, where A.exe launches B.dontrun after doing some initialization. The two processes then communicate to each other and A.exe exits after B.dontrun exits. This all behaves fine using CreateProcess and passing the executable name as the first argument when B.dontrun is named B.exe but if B.dontrun is named anything else (B.ex_ or B.bin) CreateProcess doesn't return an error, but the process isn't launched either.
I'd like B.dontrun to be named something that doesn't encourage people to run it directly, when they look in the directory they see A.exe and B.dontrun and there isn't confusion of which executable that they should be running.
At least up till and including Windows XP, the [cmd.exe] command interpreter recognizes a PE executable as such regardless of the filename extension, and runs it.
Which is one reason why it's not a good idea to start a text document with the letters "MZ"... ;-)
And which means that it’s not a good idea to try to prevent execution via filename mangling.
Instead, make the other process a DLL, and launch it via rundll32.
Cheers & hth.,
You need to specify the exe name in the cmd line argument rather than in the application name.
This works:
STARTUPINFO info;
ZeroMemory(&info, sizeof(info)); info.cb = sizeof(info);
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
TCHAR sz[1000]; // Note: lpCommandLine must be writable
lstrcpy(sz, L"c:\\users\\serge\\desktop\\notepad.dontrun");
CreateProcess(NULL, sz, NULL, NULL, FALSE, 0, NULL, NULL, &info, &pi);
printf("Error = %u\n", GetLastError());
This indeed gives a File not found error (2):
STARTUPINFO info;
ZeroMemory(&info, sizeof(info)); info.cb = sizeof(info);
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
CreateProcess(L"c:\\users\\serge\\desktop\\notepad.dontrun",
NULL, NULL, NULL, FALSE, 0, NULL, NULL, &info, &pi);
printf("Error = %u\n", GetLastError());
Note: Tested on Win7 x64
You should create the file as hidden.
CreateFile has an attribute you can use
FILE_ATTRIBUTE_HIDDEN 2 (0x2) The file is hidden. Do not include it in an ordinary directory listing.
Documentation here: http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx
I need to read data added to the end of an executable from within that executable .
On win32 I have a problem that I cannot open the .exe for reading. I have tried CreateFile and std::ifstream.
Is there a way of specifying non-exclusive read access to a file that wasn't initially opened with sharing.
EDIT- Great thing about stackoverflow, you ask the wrong question and get the right answer.
Why not just use resources which are designed for this functionality. It won't be at the end, but it will be in the executable.
If you are adding to the .exe after it is built -- you don't have to add to the end, you can update resources on a built .exe
http://msdn.microsoft.com/en-us/library/ms648049(VS.85).aspx
We do this in one of our projects. What's the problem with it? If the EXE is running, then it's already held open for reading, and you can continue to open it read-only multiple times. I just checked our code, we just use:
HANDLE file=CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
This works without problem on all versions of 32- and 64-bit Windows to date.
I have no problem opening the executable image of a process using either of these statements:
FILE* f = fopen( fname, "rb");
hFile = CreateFile( fname, FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
What's your code?