Recently, I've studied dll injection techniques and I tested them. One of those was dll injection by CreateRemoteThread and NtCreateThreadEx. I investigated CreateRemoteThread and I fount out that it called NtCreateThreadEx internally. The thing is, CreateRemoteThread works fine but NtCreateThreadEx doesn't. The code is as follows.
struct NtCreateThreadExBuffer {
ULONG Size;
ULONG Unknown1;
ULONG Unknown2;
PULONG Unknown3;
ULONG Unknown4;
ULONG Unknown5;
ULONG Unknown6;
PULONG Unknown7;
ULONG Unknown8;
};
typedef NTSTATUS(WINAPI *LPFUN_NtCreateThreadEx) (
OUT PHANDLE hThread,
IN ACCESS_MASK DesiredAccess,
IN LPVOID ObjectAttributes,
IN HANDLE ProcessHandle,
IN LPTHREAD_START_ROUTINE lpStartAddress,
IN LPVOID lpParameter,
IN BOOL CreateSuspended,
IN ULONG StackZeroBits,
IN ULONG SizeOfStackCommit,
IN ULONG SizeOfStackReserve,
OUT LPVOID lpBytesBuffer
);
...
HMODULE ntdll = GetModuleHandle(L"ntdll.dll");
HMODULE kernel32 = GetModuleHandle(L"kernel32.dll");
PTHREAD_START_ROUTINE ntCreateThreadExAddr = (PTHREAD_START_ROUTINE)GetProcAddress(ntdll, "NtCreateThreadEx");
lpfnLoadLibrary = GetProcAddress(kernel32, "LoadLibraryA");
NtCreateThreadExBuffer ntbuffer;
DWORD dwTmp1 = 0;
DWORD dwTmp2 = 0;
memset(&ntbuffer, 0, sizeof(NtCreateThreadExBuffer));
if (ntCreateThreadExAddr)
{
ntbuffer.Size = sizeof(struct NtCreateThreadExBuffer);
ntbuffer.Unknown1 = 0x10003;
ntbuffer.Unknown2 = 0x8;
ntbuffer.Unknown3 = &dwTmp2;
ntbuffer.Unknown4 = 0;
ntbuffer.Unknown5 = 0x10004;
ntbuffer.Unknown6 = 4;
ntbuffer.Unknown7 = &dwTmp1;
ntbuffer.Unknown8 = 0;
LPFUN_NtCreateThreadEx funNtCreateThreadEx = (LPFUN_NtCreateThreadEx)ntCreateThreadExAddr;
NTSTATUS status = 0;
status = funNtCreateThreadEx(
&hThread,
0x1FFFFF,
NULL,
hCurrp,
(LPTHREAD_START_ROUTINE)lpfnLoadLibrary,
(LPVOID)param,
FALSE,
NULL,
NULL,
NULL,
&ntbuffer
);
}
The funny thing about this code is that error code is 31 and status is -1073741819. If anyone knows about this one, please teach me. Thanks in advance.