From ef7deb59d48e94f85b002278ee6140583fc28931 Mon Sep 17 00:00:00 2001 From: Mattiwatti Date: Sat, 29 Jul 2017 00:37:22 +0200 Subject: [PATCH] Add InitNativeDebug and InitNativeDebugW API functions for executables that cannot be started with CreateProcess --- SDK/C/TitanEngine.h | 2 + SDK/CPP/TitanEngine.h | 2 + SDK/CPP/TitanEngine.hpp | 8 + SDK/Delphi/TitanEngine.pas | 1 + SDK/LUA/TitanEngine.lua | 3 + SDK/MASM/TitanEngine.INC | 2 + SDK/Python/TitanEngine.py | 2 + TitanEngine/TitanEngine.Debugger.cpp | 300 +++++++++++++++++++++++++++ TitanEngine/TitanEngine.def | 2 + TitanEngine/definitions.h | 2 + 10 files changed, 324 insertions(+) diff --git a/SDK/C/TitanEngine.h b/SDK/C/TitanEngine.h index ef674f8..d65ec8b 100644 --- a/SDK/C/TitanEngine.h +++ b/SDK/C/TitanEngine.h @@ -823,6 +823,8 @@ __declspec(dllexport) long TITCALL LengthDisassembleEx(HANDLE hProcess, LPVOID D __declspec(dllexport) long TITCALL LengthDisassemble(LPVOID DisassmAddress); __declspec(dllexport) void* TITCALL InitDebug(char* szFileName, char* szCommandLine, char* szCurrentFolder); __declspec(dllexport) void* TITCALL InitDebugW(const wchar_t* szFileName, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder); +__declspec(dllexport) void* TITCALL InitNativeDebug(char* szFileName, char* szCommandLine, char* szCurrentFolder); +__declspec(dllexport) void* TITCALL InitNativeDebugW(const wchar_t* szFileName, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder); __declspec(dllexport) void* TITCALL InitDebugEx(const char* szFileName, const char* szCommandLine, const char* szCurrentFolder, LPVOID EntryCallBack); __declspec(dllexport) void* TITCALL InitDebugExW(const wchar_t* szFileName, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder, LPVOID EntryCallBack); __declspec(dllexport) void* TITCALL InitDLLDebug(const char* szFileName, bool ReserveModuleBase, const char* szCommandLine, const char* szCurrentFolder, LPVOID EntryCallBack); diff --git a/SDK/CPP/TitanEngine.h b/SDK/CPP/TitanEngine.h index d4e606c..fbd9cf6 100644 --- a/SDK/CPP/TitanEngine.h +++ b/SDK/CPP/TitanEngine.h @@ -677,6 +677,8 @@ __declspec(dllimport) long TITCALL LengthDisassembleEx(HANDLE hProcess, LPVOID D __declspec(dllimport) long TITCALL LengthDisassemble(LPVOID DisassmAddress); __declspec(dllimport) void* TITCALL InitDebug(char* szFileName, char* szCommandLine, char* szCurrentFolder); __declspec(dllimport) void* TITCALL InitDebugW(wchar_t* szFileName, wchar_t* szCommandLine, wchar_t* szCurrentFolder); +__declspec(dllimport) void* TITCALL InitNativeDebug(char* szFileName, char* szCommandLine, char* szCurrentFolder); +__declspec(dllimport) void* TITCALL InitNativeDebugW(wchar_t* szFileName, wchar_t* szCommandLine, wchar_t* szCurrentFolder); __declspec(dllimport) void* TITCALL InitDebugEx(char* szFileName, char* szCommandLine, char* szCurrentFolder, LPVOID EntryCallBack); __declspec(dllimport) void* TITCALL InitDebugExW(wchar_t* szFileName, wchar_t* szCommandLine, wchar_t* szCurrentFolder, LPVOID EntryCallBack); __declspec(dllimport) void* TITCALL InitDLLDebug(char* szFileName, bool ReserveModuleBase, char* szCommandLine, char* szCurrentFolder, LPVOID EntryCallBack); diff --git a/SDK/CPP/TitanEngine.hpp b/SDK/CPP/TitanEngine.hpp index 89f8827..2538de8 100644 --- a/SDK/CPP/TitanEngine.hpp +++ b/SDK/CPP/TitanEngine.hpp @@ -1491,6 +1491,10 @@ public: { return (const PROCESS_INFORMATION*)UE::InitDebug((char*)szFileName, (char*)szCommandLine, (char*)szCurrentFolder); } + static const PROCESS_INFORMATION* InitNativeDebug(const char* szFileName, const char* szCommandLine, const char* szCurrentFolder) + { + return (const PROCESS_INFORMATION*)UE::InitNativeDebug((char*)szFileName, (char*)szCommandLine, (char*)szCurrentFolder); + } static const PROCESS_INFORMATION* InitDebugEx(const char* szFileName, const char* szCommandLine, const char* szCurrentFolder, DebuggerX::fBreakPointCallback EntryCallBack) { return (const PROCESS_INFORMATION*)UE::InitDebugEx((char*)szFileName, (char*)szCommandLine, (char*)szCurrentFolder, (void*)EntryCallBack); @@ -1513,6 +1517,10 @@ public: { return (const PROCESS_INFORMATION*)UE::InitDebugW((wchar_t*)szFileName, (wchar_t*)szCommandLine, (wchar_t*)szCurrentFolder); } + static const PROCESS_INFORMATION* InitNativeDebug(const wchar_t* szFileName, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder) + { + return (const PROCESS_INFORMATION*)UE::InitNativeDebugW((wchar_t*)szFileName, (wchar_t*)szCommandLine, (wchar_t*)szCurrentFolder); + } static const PROCESS_INFORMATION* InitDebugEx(const wchar_t* szFileName, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder, DebuggerX::fBreakPointCallback EntryCallBack) { return (const PROCESS_INFORMATION*)UE::InitDebugExW((wchar_t*)szFileName, (wchar_t*)szCommandLine, (wchar_t*)szCurrentFolder, (void*)EntryCallBack); diff --git a/SDK/Delphi/TitanEngine.pas b/SDK/Delphi/TitanEngine.pas index 736d162..bf73377 100644 --- a/SDK/Delphi/TitanEngine.pas +++ b/SDK/Delphi/TitanEngine.pas @@ -507,6 +507,7 @@ const function LengthDisassembleEx(hProcess:THandle; DisassmAddress:Pointer):LongInt; stdcall; external 'TitanEngine.dll' name 'LengthDisassembleEx'; function LengthDisassemble(DisassmAddress:Pointer):LongInt; stdcall; external 'TitanEngine.dll' name 'LengthDisassemble'; function InitDebug(szFileName,szCommandLine,szCurrentFolder:PAnsiChar): Pointer; stdcall; external 'TitanEngine.dll' name 'InitDebug'; + function InitNativeDebug(szFileName,szCommandLine,szCurrentFolder:PAnsiChar): Pointer; stdcall; external 'TitanEngine.dll' name 'InitNonWin32Debug'; function InitDebugEx(szFileName,szCommandLine,szCurrentFolder:PAnsiChar; EntryCallBack:Pointer): Pointer; stdcall; external 'TitanEngine.dll' name 'InitDebugEx'; function InitDLLDebug(szFileName:PAnsiChar; ReserveModuleBase:boolean; szCommandLine,szCurrentFolder:PAnsiChar; EntryCallBack:Pointer): Pointer; stdcall; external 'TitanEngine.dll' name 'InitDLLDebug'; function StopDebug(): Boolean; stdcall; external 'TitanEngine.dll' name 'StopDebug'; diff --git a/SDK/LUA/TitanEngine.lua b/SDK/LUA/TitanEngine.lua index 4850609..351fdca 100644 --- a/SDK/LUA/TitanEngine.lua +++ b/SDK/LUA/TitanEngine.lua @@ -783,6 +783,9 @@ PROCESS_INFORMATION = alien.defstruct{ -- __declspec(dllexport) void* __stdcall InitDebug(char* szFileName, char* szCommandLine, char* szCurrentFolder); TitanEngine.InitDebug:types {"string","string","string",abi="stdcall",ret="pointer"} TE_InitDebug = TitanEngine.InitDebug +-- __declspec(dllexport) void* __stdcall InitNativeDebug(char* szFileName, char* szCommandLine, char* szCurrentFolder); + TitanEngine.InitNativeDebug:types {"string","string","string",abi="stdcall",ret="pointer"} + InitNativeDebug = TitanEngine.InitNativeDebug -- __declspec(dllexport) void* __stdcall InitDebugEx(char* szFileName, char* szCommandLine, char* szCurrentFolder, LPVOID EntryCallBack); TitanEngine.InitDebugEx:types {"string","string","string","callback",abi="stdcall",ret="pointer"} TE_InitDebugEx = TitanEngine.InitDebugEx diff --git a/SDK/MASM/TitanEngine.INC b/SDK/MASM/TitanEngine.INC index c624514..1330db8 100644 --- a/SDK/MASM/TitanEngine.INC +++ b/SDK/MASM/TitanEngine.INC @@ -560,6 +560,8 @@ LengthDisassembleEx proto stdcall :HANDLE, :LPVOID LengthDisassemble proto stdcall :LPVOID InitDebug proto stdcall :ptr SBYTE, :ptr SBYTE, :ptr SBYTE InitDebugW proto stdcall :ptr WORD, :ptr WORD, :ptr WORD +InitNativeDebug proto stdcall :ptr SBYTE, :ptr SBYTE, :ptr SBYTE +InitNativeDebugW proto stdcall :ptr WORD, :ptr WORD, :ptr WORD InitDebugEx proto stdcall :ptr SBYTE, :ptr SBYTE, :ptr SBYTE, :LPVOID InitDebugExW proto stdcall :ptr WORD, :ptr WORD, :ptr WORD, :LPVOID InitDLLDebug proto stdcall :ptr SBYTE, :bool, :ptr SBYTE, :ptr SBYTE, :LPVOID diff --git a/SDK/Python/TitanEngine.py b/SDK/Python/TitanEngine.py index 7c1a744..ea13188 100644 --- a/SDK/Python/TitanEngine.py +++ b/SDK/Python/TitanEngine.py @@ -648,6 +648,8 @@ TE.ThreaderGetThreadInfo.restype = POINTER(THREAD_ITEM_DATA) TE.InitDebug.restype = POINTER(PROCESS_INFORMATION) TE.InitDebugW.restype = POINTER(PROCESS_INFORMATION) +TE.InitNativeDebug.restype = POINTER(PROCESS_INFORMATION) +TE.InitNativeDebugW.restype = POINTER(PROCESS_INFORMATION) TE.InitDebugEx.restype = POINTER(PROCESS_INFORMATION) TE.InitDebugExW.restype = POINTER(PROCESS_INFORMATION) TE.InitDLLDebug.restype = POINTER(PROCESS_INFORMATION) diff --git a/TitanEngine/TitanEngine.Debugger.cpp b/TitanEngine/TitanEngine.Debugger.cpp index bc6badf..f7e3964 100644 --- a/TitanEngine/TitanEngine.Debugger.cpp +++ b/TitanEngine/TitanEngine.Debugger.cpp @@ -99,6 +99,306 @@ __declspec(dllexport) void* TITCALL InitDebugW(wchar_t* szFileName, wchar_t* szC } } +__declspec(dllexport) void* TITCALL InitNativeDebug(char* szFileName, char* szCommandLine, char* szCurrentFolder) +{ + wchar_t* PtrUniFileName = NULL; + wchar_t uniFileName[MAX_PATH] = {}; + wchar_t* PtrUniCommandLine = NULL; + wchar_t uniCommandLine[MAX_PATH] = {}; + wchar_t* PtrUniCurrentFolder = NULL; + wchar_t uniCurrentFolder[MAX_PATH] = {}; + + if(szFileName != NULL) + { + MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName) + 1, uniFileName, sizeof(uniFileName) / (sizeof(uniFileName[0]))); + MultiByteToWideChar(CP_ACP, NULL, szCommandLine, lstrlenA(szCommandLine) + 1, uniCommandLine, sizeof(uniCommandLine) / (sizeof(uniCommandLine[0]))); + MultiByteToWideChar(CP_ACP, NULL, szCurrentFolder, lstrlenA(szCurrentFolder) + 1, uniCurrentFolder, sizeof(uniCurrentFolder) / (sizeof(uniCurrentFolder[0]))); + if(szFileName != NULL) + { + PtrUniFileName = &uniFileName[0]; + } + if(szCommandLine != NULL) + { + PtrUniCommandLine = &uniCommandLine[0]; + } + if(szCurrentFolder != NULL) + { + PtrUniCurrentFolder = &uniCurrentFolder[0]; + } + return(InitNativeDebugW(PtrUniFileName, PtrUniCommandLine, PtrUniCurrentFolder)); + } + else + { + return NULL; + } +} + +__declspec(dllexport) void* TITCALL InitNativeDebugW(wchar_t* szFileName, wchar_t* szCommandLine, wchar_t* szCurrentFolder) +{ + typedef + NTSTATUS + (NTAPI * + t_RtlCreateProcessParametersEx)( + _Out_ PRTL_USER_PROCESS_PARAMETERS * pProcessParameters, + _In_ PUNICODE_STRING ImagePathName, + _In_opt_ PUNICODE_STRING DllPath, + _In_opt_ PUNICODE_STRING CurrentDirectory, + _In_opt_ PUNICODE_STRING CommandLine, + _In_opt_ PVOID Environment, + _In_opt_ PUNICODE_STRING WindowTitle, + _In_opt_ PUNICODE_STRING DesktopInfo, + _In_opt_ PUNICODE_STRING ShellInfo, + _In_opt_ PUNICODE_STRING RuntimeData, + _In_ ULONG Flags + ); + + typedef + NTSTATUS + (NTAPI * + t_NtCreateUserProcess)( + _Out_ PHANDLE ProcessHandle, + _Out_ PHANDLE ThreadHandle, + _In_ ACCESS_MASK ProcessDesiredAccess, + _In_ ACCESS_MASK ThreadDesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ProcessObjectAttributes, + _In_opt_ POBJECT_ATTRIBUTES ThreadObjectAttributes, + _In_ ULONG ProcessFlags, + _In_ ULONG ThreadFlags, + _In_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters, + _Inout_ PPS_CREATE_INFO CreateInfo, + _In_ PPS_ATTRIBUTE_LIST AttributeList + ); + + HMODULE Ntdll = GetModuleHandleW(L"ntdll.dll"); + t_RtlCreateProcessParametersEx fnRtlCreateProcessParametersEx = + (t_RtlCreateProcessParametersEx)GetProcAddress(Ntdll, "RtlCreateProcessParametersEx"); + t_NtCreateUserProcess fnNtCreateUserProcess = + (t_NtCreateUserProcess)GetProcAddress(Ntdll, "NtCreateUserProcess"); + + // NtCreateUserProcess requires Vista or higher + if(fnRtlCreateProcessParametersEx == NULL || fnNtCreateUserProcess == NULL) + { + RtlSetLastWin32Error(ERROR_NOT_SUPPORTED); + return NULL; + } + + RtlZeroMemory(&dbgProcessInformation, sizeof(PROCESS_INFORMATION)); + HANDLE ProcessHandle = NULL, ThreadHandle = NULL; + UNICODE_STRING CommandLine = { 0 }; + PUNICODE_STRING PtrCurrentDirectory = NULL; + + // Convert the application path to its NT equivalent + UNICODE_STRING ImagePath, NtImagePath; + RtlInitUnicodeString(&ImagePath, szFileName); + if(!RtlDosPathNameToNtPathName_U(ImagePath.Buffer, + &NtImagePath, + NULL, + NULL)) + { + RtlSetLastWin32Error(ERROR_PATH_NOT_FOUND); + return NULL; + } + + // Enable SE_DEBUG if needed + const LONG SE_DEBUG_PRIVILEGE = 20L; + BOOLEAN SeDebugWasEnabled = FALSE; + NTSTATUS Status = STATUS_SUCCESS; + if(engineEnableDebugPrivilege) + { + Status = RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, + TRUE, + FALSE, + &SeDebugWasEnabled); + DebugRemoveDebugPrivilege = true; + } + if(!NT_SUCCESS(Status)) + goto finished; + + // Convert command line and directory to UNICODE_STRING if present + SIZE_T ArgumentsLength = lstrlenW(szCommandLine); + if(szCommandLine != NULL && ArgumentsLength > 0) + { + SIZE_T BufferSize = ImagePath.Length + ((ArgumentsLength + 4) * sizeof(wchar_t)); + CommandLine.Buffer = (PWSTR)RtlAllocateHeap(RtlProcessHeap(), HEAP_ZERO_MEMORY, BufferSize); + CommandLine.MaximumLength = (USHORT)BufferSize; + RtlAppendUnicodeToString(&CommandLine, L"\""); + RtlAppendUnicodeStringToString(&CommandLine, &ImagePath); + RtlAppendUnicodeToString(&CommandLine, L"\" "); + RtlAppendUnicodeToString(&CommandLine, szCommandLine); + } + + if(szCurrentFolder != NULL && lstrlenW(szCurrentFolder) > 0) + { + UNICODE_STRING WorkingDirectory; + RtlInitUnicodeString(&WorkingDirectory, szCurrentFolder); + PtrCurrentDirectory = &WorkingDirectory; + } + + // Create the process parameter block + PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL; + PRTL_USER_PROCESS_PARAMETERS OwnParameters = NtCurrentPeb()->ProcessParameters; + Status = fnRtlCreateProcessParametersEx(&ProcessParameters, + &ImagePath, + NULL, // Create a new DLL path + PtrCurrentDirectory, + &CommandLine, + NULL, // If null, a new environment will be created + &ImagePath, // Window title is the exe path - needed for console apps + &OwnParameters->DesktopInfo, // Copy our desktop name + NULL, + NULL, + RTL_USER_PROCESS_PARAMETERS_NORMALIZED); + if(!NT_SUCCESS(Status)) + goto finished; + + // Clear the current directory because we're not inheriting handles + ProcessParameters->CurrentDirectory.Handle = NULL; + + // Default to CREATE_NEW_CONSOLE behaviour + ProcessParameters->ConsoleHandle = HANDLE_CREATE_NEW_CONSOLE; + ProcessParameters->ShowWindowFlags = STARTF_USESHOWWINDOW | SW_SHOWDEFAULT; + + // Create a debug port object + OBJECT_ATTRIBUTES ObjectAttributes; + InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); + HANDLE DebugPort = NULL; + Status = NtCreateDebugObject(&DebugPort, + DEBUG_ALL_ACCESS, + &ObjectAttributes, + DEBUG_KILL_ON_CLOSE); + if(!NT_SUCCESS(Status)) + { + RtlDestroyProcessParameters(ProcessParameters); + goto finished; + } + + // Store the debug port handle in our TEB. The kernel uses this field + NtCurrentTeb()->DbgSsReserved[1] = DebugPort; + + // Initialize the PS_CREATE_INFO structure + PS_CREATE_INFO CreateInfo; + RtlZeroMemory(&CreateInfo, sizeof(CreateInfo)); + CreateInfo.Size = sizeof(CreateInfo); + CreateInfo.State = PsCreateInitialState; + CreateInfo.InitState.u1.s1.WriteOutputOnExit = TRUE; + CreateInfo.InitState.u1.s1.DetectManifest = TRUE; + CreateInfo.InitState.u1.s1.ProhibitedImageCharacteristics = 0; // Normally: IMAGE_FILE_DLL (disallow executing DLLs) + CreateInfo.InitState.AdditionalFileAccess = FILE_READ_ATTRIBUTES | FILE_READ_DATA; + + // Initialize the PS_ATTRIBUTE_LIST that contains the process creation attributes + const SIZE_T NumAttributes = 3; + const SIZE_T AttributesSize = sizeof(SIZE_T) + NumAttributes * sizeof(PS_ATTRIBUTE); + PPS_ATTRIBUTE_LIST AttributeList = reinterpret_cast( + RtlAllocateHeap(RtlProcessHeap(), + HEAP_ZERO_MEMORY, // Not optional + AttributesSize)); + AttributeList->TotalLength = AttributesSize; + + // In: NT style absolute image path. This is the only required attribute + ULONG N = 0; + AttributeList->Attributes[N].Attribute = PS_ATTRIBUTE_IMAGE_NAME; + AttributeList->Attributes[N].Size = NtImagePath.Length; + AttributeList->Attributes[N].Value = reinterpret_cast(NtImagePath.Buffer); + + // In: debug port + N++; + AttributeList->Attributes[N].Attribute = PS_ATTRIBUTE_DEBUG_PORT; + AttributeList->Attributes[N].Size = sizeof(HANDLE); + AttributeList->Attributes[N].Value = reinterpret_cast(DebugPort); + + // Out: client ID + N++; + CLIENT_ID Cid; + PCLIENT_ID ClientId = &Cid; + AttributeList->Attributes[N].Attribute = PS_ATTRIBUTE_CLIENT_ID; + AttributeList->Attributes[N].Size = sizeof(CLIENT_ID); + AttributeList->Attributes[N].Value = reinterpret_cast(ClientId); + + // Set process and thread flags + ULONG NtProcessFlags = PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT; // Same as DEBUG_ONLY_THIS_PROCESS. DEBUG_PROCESS is implied by the debug port + ULONG NtThreadFlags = THREAD_CREATE_FLAGS_CREATE_SUSPENDED; // Always set this, because we need to do some bookkeeping before resuming + + // Create the process + Status = fnNtCreateUserProcess(&ProcessHandle, + &ThreadHandle, + MAXIMUM_ALLOWED, + MAXIMUM_ALLOWED, + NULL, + NULL, + NtProcessFlags, + NtThreadFlags, + ProcessParameters, + &CreateInfo, + AttributeList); + + RtlFreeHeap(RtlProcessHeap(), 0, AttributeList); + RtlDestroyProcessParameters(ProcessParameters); + + if(!NT_SUCCESS(Status)) + goto finished; + + // Success. Convert what we got back to a PROCESS_INFORMATION structure + dbgProcessInformation.hProcess = ProcessHandle; + dbgProcessInformation.hThread = ThreadHandle; + dbgProcessInformation.dwProcessId = HandleToULong(ClientId->UniqueProcess); + dbgProcessInformation.dwThreadId = HandleToULong(ClientId->UniqueThread); + +finished: + RtlFreeHeap(RtlProcessHeap(), 0, NtImagePath.Buffer); + + if(CommandLine.Buffer != NULL) + RtlFreeHeap(RtlProcessHeap(), 0, CommandLine.Buffer); + + if(ProcessHandle != NULL) + { + // Close the file and section handles we got back from the kernel + NtClose(CreateInfo.SuccessState.FileHandle); + NtClose(CreateInfo.SuccessState.SectionHandle); + + // If we failed, terminate the process + if(!NT_SUCCESS(Status)) + { + BOOLEAN CloseDebugPort = DebugPort != NULL && + ((NtThreadFlags & PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT) != 0); + + if(CloseDebugPort) + { + NtRemoveProcessDebug(ProcessHandle, DebugPort); + NtClose(DebugPort); + NtCurrentTeb()->DbgSsReserved[1] = NULL; + } + + NtTerminateProcess(ProcessHandle, Status); + } + else + { + // Otherwise resume the process now + NtResumeThread(ThreadHandle, NULL); + } + } + + // Release SE_DEBUG if we acquired it previously + if(engineEnableDebugPrivilege && !SeDebugWasEnabled) + RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, + FALSE, + FALSE, + &SeDebugWasEnabled); + + if(!NT_SUCCESS(Status)) + { + // Set error status + ULONG Win32Error = RtlNtStatusToDosError(Status); + RtlSetLastWin32Error(Win32Error); + DebugRemoveDebugPrivilege = false; + return NULL; + } + + DebugAttachedToProcess = false; + DebugAttachedProcessCallBack = NULL; + + return &dbgProcessInformation; +} + __declspec(dllexport) void* TITCALL InitDebugEx(char* szFileName, char* szCommandLine, char* szCurrentFolder, LPVOID EntryCallBack) { DebugExeFileEntryPointCallBack = EntryCallBack; diff --git a/TitanEngine/TitanEngine.def b/TitanEngine/TitanEngine.def index 96df42f..d845651 100644 --- a/TitanEngine/TitanEngine.def +++ b/TitanEngine/TitanEngine.def @@ -82,6 +82,8 @@ FixHeaderCheckSum FixHeaderCheckSumW InitDebug InitDebugW +InitNativeDebug +InitNativeDebugW InitDebugEx InitDebugExW InitDLLDebug diff --git a/TitanEngine/definitions.h b/TitanEngine/definitions.h index e2c23e1..73cd527 100644 --- a/TitanEngine/definitions.h +++ b/TitanEngine/definitions.h @@ -160,6 +160,8 @@ __declspec(dllexport) long TITCALL LengthDisassembleEx(HANDLE hProcess, LPVOID D __declspec(dllexport) long TITCALL LengthDisassemble(LPVOID DisassmAddress); __declspec(dllexport) void* TITCALL InitDebug(char* szFileName, char* szCommandLine, char* szCurrentFolder); __declspec(dllexport) void* TITCALL InitDebugW(wchar_t* szFileName, wchar_t* szCommandLine, wchar_t* szCurrentFolder); +__declspec(dllexport) void* TITCALL InitNativeDebug(char* szFileName, char* szCommandLine, char* szCurrentFolder); +__declspec(dllexport) void* TITCALL InitNativeDebugW(wchar_t* szFileName, wchar_t* szCommandLine, wchar_t* szCurrentFolder); __declspec(dllexport) void* TITCALL InitDebugEx(char* szFileName, char* szCommandLine, char* szCurrentFolder, LPVOID EntryCallBack); __declspec(dllexport) void* TITCALL InitDebugExW(wchar_t* szFileName, wchar_t* szCommandLine, wchar_t* szCurrentFolder, LPVOID EntryCallBack); __declspec(dllexport) void* TITCALL InitDLLDebug(char* szFileName, bool ReserveModuleBase, char* szCommandLine, char* szCurrentFolder, LPVOID EntryCallBack);