Last active
October 15, 2015 23:03
-
-
Save valerysntx/94334eba1d1ac35cfeed to your computer and use it in GitHub Desktop.
x86 host x64
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef _OS_STRUCTS_H_ | |
#define _OS_STRUCTS_H_ | |
namespace WOW64 | |
{ | |
#pragma pack (1) | |
typedef struct _LIST_ENTRY64 | |
{ | |
union | |
{ | |
DWORD64 _Flink; | |
LIST_ENTRY64* Flink; | |
}; | |
union | |
{ | |
DWORD64 _Blink; | |
LIST_ENTRY64* Blink; | |
}; | |
} LIST_ENTRY64; | |
typedef struct UNICODE_STRING64 | |
{ | |
WORD Length; | |
WORD MaximumLength; | |
DWORD alignment; | |
union | |
{ | |
DWORD64 _Buffer; | |
WORD* Buffer; | |
}; | |
} UNICODE_STRING64; | |
typedef struct _ANSI_STRING64 | |
{ | |
WORD Length; | |
WORD MaximumLength; | |
DWORD alignment; | |
union | |
{ | |
DWORD64 _Buffer; | |
CHAR* Buffer; | |
}; | |
} ANSI_STRING64; | |
typedef struct _LDR_DATA_TABLE_ENTRY64 | |
{ | |
LIST_ENTRY64 InLoadOrderLinks; | |
LIST_ENTRY64 InMemoryOrderLinks; | |
LIST_ENTRY64 InInitializationOrderLinks; | |
DWORD64 DllBase; | |
DWORD64 EntryPoint; | |
DWORD64 SizeOfImage; | |
UNICODE_STRING64 FullDllName; | |
UNICODE_STRING64 BaseDllName; | |
/* | |
+0x000 InLoadOrderLinks : _LIST_ENTRY | |
+0x010 InMemoryOrderLinks : _LIST_ENTRY | |
+0x020 InInitializationOrderLinks : _LIST_ENTRY | |
+0x030 DllBase : Ptr64 Void | |
+0x038 EntryPoint : Ptr64 Void | |
+0x040 SizeOfImage : Uint4B | |
+0x048 FullDllName : _UNICODE_STRING | |
+0x058 BaseDllName : _UNICODE_STRING | |
+0x068 Flags : Uint4B | |
+0x06c LoadCount : Uint2B | |
+0x06e TlsIndex : Uint2B | |
+0x070 HashLinks : _LIST_ENTRY | |
+0x070 SectionPointer : Ptr64 Void | |
+0x078 CheckSum : Uint4B | |
+0x080 TimeDateStamp : Uint4B | |
+0x080 LoadedImports : Ptr64 Void | |
+0x088 EntryPointActivationContext : Ptr64 _ACTIVATION_CONTEXT | |
+0x090 PatchInformation : Ptr64 Void | |
+0x098 ForwarderLinks : _LIST_ENTRY | |
+0x0a8 ServiceTagLinks : _LIST_ENTRY | |
+0x0b8 StaticLinks : _LIST_ENTRY | |
+0x0c8 ContextInformation : Ptr64 Void | |
+0x0d0 OriginalBase : Uint8B | |
*/ | |
} LDR_DATA_TABLE_ENTRY64; | |
typedef struct _PEB_LDR_DATA64 | |
{ | |
DWORD Length; | |
DWORD Initialized; | |
DWORD64 SsHandle; | |
LIST_ENTRY64 InLoadOrderModuleList; | |
LIST_ENTRY64 InMemoryOrderModuleList; | |
LIST_ENTRY64 InInitializationOrderModuleList; | |
DWORD64 EntryInProgress; | |
DWORD64 ShutdownInProgress; | |
DWORD64 ShutdownThreadId; | |
/* | |
+0x000 Length : Uint4B | |
+0x004 Initialized : UChar | |
+0x008 SsHandle : Ptr64 Void | |
+0x010 InLoadOrderModuleList : _LIST_ENTRY | |
+0x020 InMemoryOrderModuleList : _LIST_ENTRY | |
+0x030 InInitializationOrderModuleList : _LIST_ENTRY | |
+0x040 EntryInProgress : Ptr64 Void | |
+0x048 ShutdownInProgress : UChar | |
+0x050 ShutdownThreadId : Ptr64 Void | |
*/ | |
} PEB_LDR_DATA64; | |
typedef struct _PEB64 | |
{ | |
BYTE InheritedAddressSpace; | |
BYTE ReadImageFileExecOptions; | |
BYTE BeingDebugged; | |
BYTE BitField; | |
DWORD Reserved1; | |
DWORD64 Mutant; | |
DWORD64 ImageBaseAddress; | |
union | |
{ | |
DWORD64 _Ldr; | |
PEB_LDR_DATA64* Ldr; | |
}; | |
DWORD64 ProcessParameters; | |
DWORD64 SubSystemData; | |
DWORD64 ProcessHeap; | |
DWORD64 FastPebLock; | |
DWORD64 AtlThunkSListPtr; | |
DWORD64 IFEOKey; | |
DWORD CrossProcessFlags; | |
DWORD Reserved2; | |
DWORD64 UserSharedInfoPtr; //KernelCallbackTable | |
DWORD SystemReserved; | |
DWORD AtlThunkSListPtr32; | |
DWORD64 ApiSetMap; | |
DWORD TlsExpansionCounter; | |
DWORD Reserved3; | |
DWORD64 TlsBitmap; | |
DWORD TlsBitmapBits; | |
DWORD Reserved4; | |
DWORD64 ReadOnlySharedMemoryBase; | |
DWORD64 HotpatchInformation; | |
DWORD64 ReadOnlyStaticServerData; | |
DWORD64 AnsiCodePageData; | |
DWORD64 OemCodePageData; | |
DWORD64 UnicodeCaseTableData; | |
DWORD NumberOfProcessors; | |
DWORD NtGlobalFlag; | |
LARGE_INTEGER CriticalSectionTimeout; | |
DWORD64 HeapSegmentReserve; | |
DWORD64 HeapSegmentCommit; | |
DWORD64 HeapDeCommitTotalFreeThreshold; | |
DWORD64 HeapDeCommitFreeBlockThreshold; | |
DWORD NumberOfHeaps; | |
DWORD MaximumNumberOfHeaps; | |
DWORD64 ProcessHeaps; | |
DWORD64 GdiSharedHandleTable; | |
DWORD64 ProcessStarterHelper; | |
DWORD GdiDCAttributeList; | |
DWORD Reserved5; | |
DWORD64 LoaderLock; | |
DWORD OSMajorVersion; | |
DWORD OSMinorVersion; | |
WORD OSBuildNumber; | |
WORD OSCSDVersion; | |
DWORD OSPlatformId; | |
DWORD ImageSubsystem; | |
DWORD ImageSubsystemMajorVersion; | |
DWORD ImageSubsystemMinorVersion; | |
DWORD Reserved6; | |
DWORD64 ActiveProcessAffinityMask; | |
DWORD GdiHandleBuffer; | |
DWORD Reserved7[59]; | |
DWORD64 PostProcessInitRoutine; | |
DWORD64 TlsExpansionBitmap; | |
DWORD TlsExpansionBitmapBits; | |
DWORD Reserved8[31]; | |
DWORD SessionId; | |
DWORD Reserved9; | |
ULARGE_INTEGER AppCompatFlags; | |
ULARGE_INTEGER AppCompatFlagsUser; | |
DWORD64 pShimData; | |
DWORD64 AppCompatInfo; | |
UNICODE_STRING CSDVersion; | |
//DWORD Reserved10; | |
DWORD64 ActivationContextData; | |
DWORD64 ProcessAssemblyStorageMap; | |
DWORD64 SystemDefaultActivationContextData; | |
DWORD64 SystemAssemblyStorageMap; | |
DWORD64 MinimumStackCommit; | |
DWORD64 FlsCallback; | |
LIST_ENTRY FlsListHead; | |
DWORD64 FlsBitmap; | |
DWORD FlsBitmapBits; | |
DWORD Reserved11[3]; | |
DWORD FlsHighIndex; | |
DWORD Reserved12; | |
DWORD64 WerRegistrationData; | |
DWORD64 WerShipAssertPtr; | |
DWORD64 pContextData; | |
DWORD64 pImageHeaderHash; | |
DWORD TracingFlags; | |
} PEB64; | |
typedef struct _EXCEPTION_REGISTRATION_RECORD64 | |
{ | |
DWORD64 Next; | |
DWORD64 Handler; | |
} EXCEPTION_REGISTRATION_RECORD64; | |
/* | |
//defined in winternl.h | |
typedef struct _NT_TIB64 | |
{ | |
DWORD64 ExceptionList; | |
DWORD64 StackBase; | |
DWORD64 StackLimit; | |
DWORD64 SubSystemTib; | |
DWORD64 FiberData; | |
DWORD64 ArbitraryUserPointer; | |
DWORD64 Self; | |
} NT_TIB64; | |
*/ | |
typedef struct _CLIENT_ID64 | |
{ | |
DWORD64 UniqueProcess; | |
DWORD64 UniqueThread; | |
} CLIENT_ID64; | |
typedef struct _TEB64 | |
{ | |
_NT_TIB64 NtTib; | |
DWORD64 EnvironmentPointer; | |
_CLIENT_ID64 ClientId; | |
DWORD64 ActiveRpcHandle; | |
DWORD64 ThreadLocalStoragePointer; | |
union | |
{ | |
DWORD64 _ProcessEnvironmentBlock; | |
PEB64* ProcessEnvironmentBlock; | |
}; | |
/* | |
+0x000 NtTib : _NT_TIB | |
+0x038 EnvironmentPointer : Ptr64 Void | |
+0x040 ClientId : _CLIENT_ID | |
+0x050 ActiveRpcHandle : Ptr64 Void | |
+0x058 ThreadLocalStoragePointer : Ptr64 Void | |
+0x060 ProcessEnvironmentBlock : Ptr64 _PEB | |
+0x068 LastErrorValue : Uint4B | |
+0x06c CountOfOwnedCriticalSections : Uint4B | |
+0x070 CsrClientThread : Ptr64 Void | |
+0x078 Win32ThreadInfo : Ptr64 Void | |
+0x080 User32Reserved : [26] Uint4B | |
+0x0e8 UserReserved : [5] Uint4B | |
+0x100 WOW32Reserved : Ptr64 Void | |
+0x108 CurrentLocale : Uint4B | |
+0x10c FpSoftwareStatusRegister : Uint4B | |
+0x110 SystemReserved1 : [54] Ptr64 Void | |
+0x2c0 ExceptionCode : Int4B | |
+0x2c8 ActivationContextStackPointer : Ptr64 _ACTIVATION_CONTEXT_STACK | |
+0x2d0 SpareBytes : [24] UChar | |
+0x2e8 TxFsContext : Uint4B | |
+0x2f0 GdiTebBatch : _GDI_TEB_BATCH | |
+0x7d8 RealClientId : _CLIENT_ID | |
+0x7e8 GdiCachedProcessHandle : Ptr64 Void | |
+0x7f0 GdiClientPID : Uint4B | |
+0x7f4 GdiClientTID : Uint4B | |
+0x7f8 GdiThreadLocalInfo : Ptr64 Void | |
+0x800 Win32ClientInfo : [62] Uint8B | |
+0x9f0 glDispatchTable : [233] Ptr64 Void | |
+0x1138 glReserved1 : [29] Uint8B | |
+0x1220 glReserved2 : Ptr64 Void | |
+0x1228 glSectionInfo : Ptr64 Void | |
+0x1230 glSection : Ptr64 Void | |
+0x1238 glTable : Ptr64 Void | |
+0x1240 glCurrentRC : Ptr64 Void | |
+0x1248 glContext : Ptr64 Void | |
+0x1250 LastStatusValue : Uint4B | |
+0x1258 StaticUnicodeString : _UNICODE_STRING | |
+0x1268 StaticUnicodeBuffer : [261] Wchar | |
+0x1478 DeallocationStack : Ptr64 Void | |
+0x1480 TlsSlots : [64] Ptr64 Void | |
+0x1680 TlsLinks : _LIST_ENTRY | |
+0x1690 Vdm : Ptr64 Void | |
+0x1698 ReservedForNtRpc : Ptr64 Void | |
+0x16a0 DbgSsReserved : [2] Ptr64 Void | |
+0x16b0 HardErrorMode : Uint4B | |
+0x16b8 Instrumentation : [11] Ptr64 Void | |
+0x1710 ActivityId : _GUID | |
+0x1720 SubProcessTag : Ptr64 Void | |
+0x1728 EtwLocalData : Ptr64 Void | |
+0x1730 EtwTraceData : Ptr64 Void | |
+0x1738 WinSockData : Ptr64 Void | |
+0x1740 GdiBatchCount : Uint4B | |
+0x1744 CurrentIdealProcessor : _PROCESSOR_NUMBER | |
+0x1744 IdealProcessorValue : Uint4B | |
+0x1744 ReservedPad0 : UChar | |
+0x1745 ReservedPad1 : UChar | |
+0x1746 ReservedPad2 : UChar | |
+0x1747 IdealProcessor : UChar | |
+0x1748 GuaranteedStackBytes : Uint4B | |
+0x1750 ReservedForPerf : Ptr64 Void | |
+0x1758 ReservedForOle : Ptr64 Void | |
+0x1760 WaitingOnLoaderLock : Uint4B | |
+0x1768 SavedPriorityState : Ptr64 Void | |
+0x1770 SoftPatchPtr1 : Uint8B | |
+0x1778 ThreadPoolData : Ptr64 Void | |
+0x1780 TlsExpansionSlots : Ptr64 Ptr64 Void | |
+0x1788 DeallocationBStore : Ptr64 Void | |
+0x1790 BStoreLimit : Ptr64 Void | |
+0x1798 MuiGeneration : Uint4B | |
+0x179c IsImpersonating : Uint4B | |
+0x17a0 NlsCache : Ptr64 Void | |
+0x17a8 pShimData : Ptr64 Void | |
+0x17b0 HeapVirtualAffinity : Uint4B | |
+0x17b8 CurrentTransactionHandle : Ptr64 Void | |
+0x17c0 ActiveFrame : Ptr64 _TEB_ACTIVE_FRAME | |
+0x17c8 FlsData : Ptr64 Void | |
+0x17d0 PreferredLanguages : Ptr64 Void | |
+0x17d8 UserPrefLanguages : Ptr64 Void | |
+0x17e0 MergedPrefLanguages : Ptr64 Void | |
+0x17e8 MuiImpersonation : Uint4B | |
+0x17ec CrossTebFlags : Uint2B | |
+0x17ec SpareCrossTebBits : Pos 0, 16 Bits | |
+0x17ee SameTebFlags : Uint2B | |
+0x17ee SafeThunkCall : Pos 0, 1 Bit | |
+0x17ee InDebugPrint : Pos 1, 1 Bit | |
+0x17ee HasFiberData : Pos 2, 1 Bit | |
+0x17ee SkipThreadAttach : Pos 3, 1 Bit | |
+0x17ee WerInShipAssertCode : Pos 4, 1 Bit | |
+0x17ee RanProcessInit : Pos 5, 1 Bit | |
+0x17ee ClonedThread : Pos 6, 1 Bit | |
+0x17ee SuppressDebugMsg : Pos 7, 1 Bit | |
+0x17ee DisableUserStackWalk : Pos 8, 1 Bit | |
+0x17ee RtlExceptionAttached : Pos 9, 1 Bit | |
+0x17ee InitialThread : Pos 10, 1 Bit | |
+0x17ee SpareSameTebBits : Pos 11, 5 Bits | |
+0x17f0 TxnScopeEnterCallback : Ptr64 Void | |
+0x17f8 TxnScopeExitCallback : Ptr64 Void | |
+0x1800 TxnScopeContext : Ptr64 Void | |
+0x1808 LockCount : Uint4B | |
+0x180c SpareUlong0 : Uint4B | |
+0x1810 ResourceRetValue : Ptr64 Void | |
*/ | |
} TEB64; | |
#pragma pack() | |
}; | |
#endif //_OS_STRUCTS_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdio> | |
#include <windows.h> | |
#include <winternl.h> | |
#include "os_structs.h" | |
#define EMIT(a) __asm __emit (a) | |
#define X64_Start_with_CS(_cs) \ | |
{ \ | |
EMIT(0x6A) EMIT(_cs) /* push _cs */ \ | |
EMIT(0xE8) EMIT(0) EMIT(0) EMIT(0) EMIT(0) /* call $+5 */ \ | |
EMIT(0x83) EMIT(4) EMIT(0x24) EMIT(5) /* add dword [esp], 5 */ \ | |
EMIT(0xCB) /* retf */ \ | |
} | |
#define X64_End_with_CS(_cs) \ | |
{ \ | |
EMIT(0xE8) EMIT(0) EMIT(0) EMIT(0) EMIT(0) /* call $+5 */ \ | |
EMIT(0xC7) EMIT(0x44) EMIT(0x24) EMIT(4) EMIT(_cs) EMIT(0) EMIT(0) EMIT(0) /* mov dword [rsp + 4], _cs */ \ | |
EMIT(0x83) EMIT(4) EMIT(0x24) EMIT(0xD) /* add dword [rsp], 0xD */ \ | |
EMIT(0xCB) /* retf */ \ | |
} | |
#define X64_Start() X64_Start_with_CS(0x33) | |
#define X64_End() X64_End_with_CS(0x23) | |
#define _RAX 0 | |
#define _RCX 1 | |
#define _RDX 2 | |
#define _RBX 3 | |
#define _RSP 4 | |
#define _RBP 5 | |
#define _RSI 6 | |
#define _RDI 7 | |
#define _R8 8 | |
#define _R9 9 | |
#define _R10 10 | |
#define _R11 11 | |
#define _R12 12 | |
#define _R13 13 | |
#define _R14 14 | |
#define _R15 15 | |
#define X64_Push(r) EMIT(0x48 | ((r) >> 3)) EMIT(0x50 | ((r) & 7)) | |
#define X64_Pop(r) EMIT(0x48 | ((r) >> 3)) EMIT(0x58 | ((r) & 7)) | |
//to fool M$ inline asm compiler I'm using 2 DWORDs instead of DWORD64 | |
//use of DWORD64 will generate wrong 'pop word ptr[]' and it will break stack | |
union reg64 | |
{ | |
DWORD dw[2]; | |
DWORD64 v; | |
}; | |
WOW64::TEB64* getTEB64() | |
{ | |
reg64 reg; | |
reg.v = 0; | |
X64_Start(); | |
//R12 register should always contain pointer to TEB64 in WoW64 processes | |
X64_Push(_R12); | |
//below pop will pop QWORD from stack, as we're in x64 mode now | |
__asm pop reg.dw[0] | |
X64_End(); | |
//upper 32 bits should be always 0 in WoW64 processes | |
if (reg.dw[1] != 0) | |
return 0; | |
return (WOW64::TEB64*)reg.dw[0]; | |
} | |
DWORD getNTDLL64() | |
{ | |
static DWORD ntdll64 = 0; | |
if (ntdll64 != 0) | |
return ntdll64; | |
WOW64::TEB64* teb64 = getTEB64(); | |
WOW64::PEB64* peb64 = teb64->ProcessEnvironmentBlock; | |
WOW64::PEB_LDR_DATA64* ldr = peb64->Ldr; | |
printf("TEB: %08X\n", (DWORD)teb64); | |
printf("PEB: %08X\n", (DWORD)peb64); | |
printf("LDR: %08X\n", (DWORD)ldr); | |
printf("Loaded modules:\n"); | |
WOW64::LDR_DATA_TABLE_ENTRY64* head = (WOW64::LDR_DATA_TABLE_ENTRY64*)ldr->InLoadOrderModuleList.Flink; | |
do | |
{ | |
printf(" %ws\n", head->BaseDllName.Buffer); | |
if (memcmp(head->BaseDllName.Buffer, L"ntdll.dll", head->BaseDllName.Length) == 0) | |
ntdll64 = (DWORD)head->DllBase; | |
head = (WOW64::LDR_DATA_TABLE_ENTRY64*)head->InLoadOrderLinks.Flink; | |
} | |
while (head != (WOW64::LDR_DATA_TABLE_ENTRY64*)&ldr->InLoadOrderModuleList); | |
printf("NTDLL x64: %08X\n", ntdll64); | |
return ntdll64; | |
} | |
DWORD getLdrGetProcedureAddress() | |
{ | |
BYTE* modBase = (BYTE*)getNTDLL64(); | |
IMAGE_NT_HEADERS64* inh = (IMAGE_NT_HEADERS64*)(modBase + ((IMAGE_DOS_HEADER*)modBase)->e_lfanew); | |
IMAGE_DATA_DIRECTORY& idd = inh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; | |
if (idd.VirtualAddress == 0) | |
return 0; | |
IMAGE_EXPORT_DIRECTORY* ied = (IMAGE_EXPORT_DIRECTORY*)(modBase + idd.VirtualAddress); | |
DWORD* rvaTable = (DWORD*)(modBase + ied->AddressOfFunctions); | |
WORD* ordTable = (WORD*)(modBase + ied->AddressOfNameOrdinals); | |
DWORD* nameTable = (DWORD*)(modBase + ied->AddressOfNames); | |
//lazy search, there is no need to use binsearch for just one function | |
for (DWORD i = 0; i < ied->NumberOfFunctions; i++) | |
{ | |
if (strcmp((char*)modBase + nameTable[i], "LdrGetProcedureAddress")) | |
continue; | |
else | |
return (DWORD)(modBase + rvaTable[ordTable[i]]); | |
} | |
return 0; | |
} | |
DWORD64 X64Call(DWORD func, int argC, ...) | |
{ | |
va_list args; | |
va_start(args, argC); | |
DWORD64 _rcx = (argC > 0) ? argC--, va_arg(args, DWORD64) : 0; | |
DWORD64 _rdx = (argC > 0) ? argC--, va_arg(args, DWORD64) : 0; | |
DWORD64 _r8 = (argC > 0) ? argC--, va_arg(args, DWORD64) : 0; | |
DWORD64 _r9 = (argC > 0) ? argC--, va_arg(args, DWORD64) : 0; | |
reg64 _rax; | |
_rax.v = 0; | |
DWORD64 restArgs = (DWORD64)&va_arg(args, DWORD64); | |
//conversion to QWORD for easier use in inline assembly | |
DWORD64 _argC = argC; | |
DWORD64 _func = func; | |
DWORD back_esp = 0; | |
__asm | |
{ | |
;//keep original esp in back_esp variable | |
mov back_esp, esp | |
;//align esp to 8, without aligned stack some syscalls may return errors ! | |
and esp, 0xFFFFFFF8 | |
X64_Start(); | |
;//fill first four arguments | |
push _rcx | |
X64_Pop(_RCX); | |
push _rdx | |
X64_Pop(_RDX); | |
push _r8 | |
X64_Pop(_R8); | |
push _r9 | |
X64_Pop(_R9); | |
push edi | |
push restArgs | |
X64_Pop(_RDI); | |
push _argC | |
X64_Pop(_RAX); | |
;//put rest of arguments on the stack | |
test eax, eax | |
jz _ls_e | |
lea edi, dword ptr [edi + 8*eax - 8] | |
_ls: | |
test eax, eax | |
jz _ls_e | |
push dword ptr [edi] | |
sub edi, 8 | |
sub eax, 1 | |
jmp _ls | |
_ls_e: | |
;//create stack space for spilling registers | |
sub esp, 0x20 | |
call _func | |
;//cleanup stack | |
push _argC | |
X64_Pop(_RCX); | |
lea esp, dword ptr [esp + 8*ecx + 0x20] | |
pop edi | |
//set return value | |
X64_Push(_RAX); | |
pop _rax.dw[0] | |
X64_End(); | |
mov esp, back_esp | |
} | |
return _rax.v; | |
} | |
DWORD64 GetProcAddress64(DWORD module, char* funcName) | |
{ | |
static DWORD _LdrGetProcedureAddress = 0; | |
if (_LdrGetProcedureAddress == 0) | |
{ | |
_LdrGetProcedureAddress = getLdrGetProcedureAddress(); | |
printf("LdrGetProcedureAddress: %08X\n", _LdrGetProcedureAddress); | |
if (_LdrGetProcedureAddress == 0) | |
return 0; | |
} | |
WOW64::ANSI_STRING64 fName = { 0 }; | |
fName.Buffer = funcName; | |
fName.Length = strlen(funcName); | |
fName.MaximumLength = fName.Length + 1; | |
DWORD64 funcRet = 0; | |
X64Call(_LdrGetProcedureAddress, 4, | |
(DWORD64)module, (DWORD64)&fName, | |
(DWORD64)0, (DWORD64)&funcRet); | |
printf("%s: %08X\n", funcName, (DWORD)funcRet); | |
return funcRet; | |
} | |
int wmain(); | |
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) | |
{ | |
int argc = 0; | |
int ret = 0; | |
LPWSTR* argv = CommandLineToArgvW(GetCommandLine(), &argc); | |
if (argv) | |
{ | |
ret = wmain(); | |
LocalFree(argv); | |
} | |
return ret; | |
} | |
int wmain() | |
{ | |
DWORD hNtdll = getNTDLL64(); | |
DWORD tmp = (DWORD)GetProcAddress64(hNtdll, "A_SHAInit"); | |
system("pause"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
x86 host of x64