Answer the question
In order to leave comments, you need to log in
Why does the compiler return this error (undefined reference)?
Hello
My program injects a DLL file that installs hooks on NtCreateFile and MoveFileExW and asks the user for permission (allow copy / move the file to the specified path)
Here is the code of the DLL module:
#define MYLIBAPI extern "C" __declspec(dllexport)
#include "head.h"
#define SIZE 6
typedef int (WINAPI *pMessageBoxW)(HWND, LPCWSTR, LPCWSTR, UINT); // Messagebox prototype
typedef int (WINAPI *pCreateFile)(LPCTSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
typedef NTSTATUS (WINAPI *pNtCreateFile)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, PLARGE_INTEGER,
ULONG, ULONG, ULONG, ULONG, PVOID, ULONG);
typedef BOOL (WINAPI * pMoveFileExW)(LPCWSTR, LPCWSTR, DWORD);
int WINAPI MyMessageBoxW(HWND, LPCWSTR, LPCWSTR, UINT); // Our detour
HANDLE WINAPI MyCreateFileW(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
NTSTATUS MyNtCreateFile(
PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PIO_STATUS_BLOCK IoStatusBlock,
PLARGE_INTEGER AllocationSize,
ULONG FileAttributes,
ULONG ShareAccess,
ULONG CreateDisposition,
ULONG CreateOptions,
PVOID EaBuffer,
ULONG EaLength
);
BOOL WINAPI MyMoveFileExW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, DWORD dwFlags);
void BeginRedirect(LPVOID, BOOL);
pNtCreateFile pOrigMBAddress_1 = NULL; // address of original
BYTE oldBytes_1[SIZE] = {0}; // backup
BYTE JMP_1[SIZE] = {0}; // 6 byte JMP instruction
DWORD oldProtect_1, myProtect_1 = PAGE_EXECUTE_READWRITE;
///
pMoveFileExW pOrigMBAddress_2 = NULL; // address of original
BYTE oldBytes_2[SIZE] = {0}; // backup
BYTE JMP_2[SIZE] = {0}; // 6 byte JMP instruction
DWORD oldProtect_2, myProtect_2 = PAGE_EXECUTE_READWRITE;
INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved)
{
switch(Reason)
{
case DLL_PROCESS_ATTACH: // if attached
pOrigMBAddress_1 = (pNtCreateFile)
GetProcAddress(GetModuleHandle("NtDLL.dll"), // get address of original
"NtCreateFile");
if(pOrigMBAddress_1 != NULL){
BeginRedirect((LPVOID)&MyNtCreateFile, TRUE); // start detouring
pOrigMBAddress_2 = (pMoveFileExW)
GetProcAddress(GetModuleHandle("Kernel32.dll"), // get address of original
"MoveFileExW");
if(pOrigMBAddress_2!= NULL)
BeginRedirect((LPVOID)&MyMoveFileExW, FALSE);
}
break;
case DLL_PROCESS_DETACH:
//memcpy((LPVOID)pOrigMBAddress, oldBytes, SIZE); // restore backup
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
void BeginRedirect(LPVOID newFunction, BOOL first)
{
if(first){
BYTE tempJMP_1[SIZE] = {0xE9, 0x90, 0x90, 0x90, 0x90, 0xC3}; // 0xE9 = JMP 0x90 = NOP 0xC3 = RET
memcpy(JMP_1, tempJMP_1, SIZE); // store jmp instruction to JMP
DWORD JMPSize_1 = (reinterpret_cast<char*>(newFunction) - reinterpret_cast<char*>(pOrigMBAddress_1) - 5); // calculate jump distance
VirtualProtect((LPVOID)pOrigMBAddress_1, SIZE, // assign read write protection
PAGE_EXECUTE_READWRITE, &oldProtect_1);
memcpy(oldBytes_1, (LPVOID)pOrigMBAddress_1, SIZE); // make backup
memcpy(&JMP_1[1], &JMPSize_1, 4); // fill the nop's with the jump distance (JMP,distance(4bytes),RET)
memcpy((LPVOID)pOrigMBAddress_1, JMP_1, SIZE); // set jump instruction at the beginning of the original function
VirtualProtect((LPVOID)pOrigMBAddress_1, SIZE, oldProtect_1, NULL); // reset protection
}else{
BYTE tempJMP_2[SIZE] = {0xE9, 0x90, 0x90, 0x90, 0x90, 0xC3}; // 0xE9 = JMP 0x90 = NOP 0xC3 = RET
memcpy(JMP_2, tempJMP_2, SIZE); // store jmp instruction to JMP
DWORD JMPSize_2 = (reinterpret_cast<char*>(newFunction) - reinterpret_cast<char*>(pOrigMBAddress_2) - 5); // calculate jump distance
VirtualProtect((LPVOID)pOrigMBAddress_2, SIZE, // assign read write protection
PAGE_EXECUTE_READWRITE, &oldProtect_2);
memcpy(oldBytes_2, (LPVOID)pOrigMBAddress_2, SIZE); // make backup
memcpy(&JMP_2[1], &JMPSize_2, 4); // fill the nop's with the jump distance (JMP,distance(4bytes),RET)
memcpy((LPVOID)pOrigMBAddress_2, JMP_2, SIZE); // set jump instruction at the beginning of the original function
VirtualProtect((LPVOID)pOrigMBAddress_2, SIZE, oldProtect_2, NULL); // reset protection
}
}
NTSTATUS MyNtCreateFile(
PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PIO_STATUS_BLOCK IoStatusBlock,
PLARGE_INTEGER AllocationSize,
ULONG FileAttributes,
ULONG ShareAccess,
ULONG CreateDisposition,
ULONG CreateOptions,
PVOID EaBuffer,
ULONG EaLength
)
{
NTSTATUS retValue;
int res = IDYES;
if(CreateDisposition == FILE_CREATE && CreateOptions & FILE_NON_DIRECTORY_FILE){
res = MessageBoxW(FindWindowW(NULL, L"Корзина"), (LPCWSTR)ObjectAttributes->ObjectName->Buffer, (LPCWSTR)L"Разрешить скопировать файл по этому пути?", MB_YESNO);
}
if(res == IDYES){
VirtualProtect((LPVOID)pOrigMBAddress_1, SIZE, myProtect_1, NULL); // assign read write protection
memcpy((LPVOID)pOrigMBAddress_1, oldBytes_1, SIZE); // restore backup
retValue = NtCreateFile(FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock, AllocationSize,
FileAttributes, ShareAccess, CreateDisposition, CreateOptions,
EaBuffer, EaLength); // get return value of original function
memcpy((LPVOID)pOrigMBAddress_1, JMP_1, SIZE); // set the jump instruction again
VirtualProtect((LPVOID)pOrigMBAddress_1, SIZE, oldProtect_1, NULL); // reset protection
}
else{
retValue = 0;
}
return retValue;
}
BOOL WINAPI MyMoveFileExW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, DWORD dwFlags)
{
BOOL retValue;
int res = IDYES;
res = MessageBoxW(FindWindowW(NULL, L"Корзина"), lpNewFileName, (LPCWSTR)L"Разрешить переместить файл по этому пути?", MB_YESNO);
if(res == IDYES){
VirtualProtect((LPVOID)pOrigMBAddress_2, SIZE, myProtect_2, NULL); // assign read write protection
memcpy((LPVOID)pOrigMBAddress_2, oldBytes_2, SIZE); // restore backup
retValue = MoveFileExW(lpExistingFileName, lpNewFileName, dwFlags);
memcpy((LPVOID)pOrigMBAddress_2, JMP_2, SIZE); // set the jump instruction again
VirtualProtect((LPVOID)pOrigMBAddress_2, SIZE, oldProtect_2, NULL); // reset protection
}
else{
retValue = FALSE;
}
return retValue;
}
Answer the question
In order to leave comments, you need to log in
Well, now everything is clearer. You have such a thing in your code
And there should be a call through your previously resolved and saved pointer pOrigMBAddress_1
Similarly with the second function. By calling it "the old fashioned way", you will go into your own handler and get stuck. And the compiler produces an error because it does not know the description of NtCreateFile. For MoveFileEx, there is apparently a header file, so it does not swear.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question