From 07ec166b945703e5a884033d024fb0476ae828a5 Mon Sep 17 00:00:00 2001 From: cw2k <3834079+cw2k@users.noreply.github.com> Date: Tue, 3 Nov 2020 05:37:41 +0100 Subject: [PATCH 1/4] ConvertVAtoFileOffsetEx * now returns 0 on error (and not INVALID_VALUE => -1) * implementation for ReturnType In short I just copied that from: https://github.com/x64dbg/GleeBug/blob/c5aed9fcccb9f2161af86cfefe0ef5006e913fc9/StaticEngine/Emulator.h#L507 --- TitanEngineEmulator/Emulator.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/TitanEngineEmulator/Emulator.h b/TitanEngineEmulator/Emulator.h index 67d08ff..9ed8ac9 100644 --- a/TitanEngineEmulator/Emulator.h +++ b/TitanEngineEmulator/Emulator.h @@ -590,7 +590,10 @@ public: __debugbreak(); //return 0; if(!found->second.pe->IsValidPe()) __debugbreak(); //return 0; - return found->second.pe->ConvertRvaToOffset(uint32(AddressToConvert)); + auto offset = found->second.pe->ConvertRvaToOffset(uint32(AddressToConvert)); + if (offset == INVALID_VALUE) + return 0; + return ReturnType ? FileMapVA + offset : offset; } template @@ -1200,4 +1203,4 @@ private: //variables STEPCALLBACK mCbATTACHBREAKPOINT = nullptr; PROCESS_INFORMATION* mAttachProcessInfo = nullptr; wchar_t szDebuggeeName[MAX_PATH] = L""; -}; \ No newline at end of file +}; From 951852bab1d1127f9a8d7adfcaa37e9be1d06362 Mon Sep 17 00:00:00 2001 From: cw2k <3834079+cw2k@users.noreply.github.com> Date: Tue, 3 Nov 2020 21:52:22 +0100 Subject: [PATCH 2/4] ConvertVAtoFileOffsetEx() now supports VA values * ConvertVAtoFileOffsetEx(): implemented a handler for the bool AddressIsRVA. Before AddressToConvert was always assumed to be a RVA what lead to problems if a VA was passed in AddressToConvert [what was shown by AddressIsRVA=true] Combined with previous bug that returns INVALID_VALUE in case of an error it crashed the gleebug clientapp since they interpreted INVALID_VALUE as a file offset * ConvertFileOffsetToVA: fix for return value. In case an error occurs it now returns 0. Before it returned INVALID_VALUE. * Start commenting function purpose and it's parameters --- TitanEngineEmulator/Emulator.h | 54 ++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/TitanEngineEmulator/Emulator.h b/TitanEngineEmulator/Emulator.h index 9ed8ac9..8df767c 100644 --- a/TitanEngineEmulator/Emulator.h +++ b/TitanEngineEmulator/Emulator.h @@ -571,29 +571,71 @@ public: ULONG_PTR ConvertFileOffsetToVA(ULONG_PTR FileMapVA, ULONG_PTR AddressToConvert, bool ReturnType) { auto found = mappedFiles.find(FileMapVA); + if(found == mappedFiles.end()) __debugbreak(); //return 0; + if(!found->second.pe->IsValidPe()) __debugbreak(); //return 0; - return found->second.pe->ConvertOffsetToRva(uint32(AddressToConvert)); + + auto offset = found->second.pe->ConvertOffsetToRva( uint32( AddressToConvert ) ); + + if (offset == INVALID_VALUE) + return 0; } - ULONG_PTR ConvertVAtoFileOffset(ULONG_PTR FileMapVA, ULONG_PTR AddressToConvert, bool ReturnType) + //// + /// + // ConvertVAtoFileOffset - converts virtual addresses to its physical counterpart. + // + // Returns: converted physical address + // or NULL if conversion has failed. + // + ULONG_PTR ConvertVAtoFileOffset( + ULONG_PTR FileMapVA, // [in] Pointer to the mapped file content. It's either StaticFileLoad function or Windows API for file mapping. + ULONG_PTR AddressToConvert, // [in] Virtual address to convert to a physical address. + bool ReturnType // [in] Add the FileMapVA return value? + ) { - return ConvertVAtoFileOffsetEx(FileMapVA, 0, 0, AddressToConvert, false, ReturnType); + return ConvertVAtoFileOffsetEx( + FileMapVA ,0 ,0 , + AddressToConvert, false, ReturnType ); } - ULONG_PTR ConvertVAtoFileOffsetEx(ULONG_PTR FileMapVA, DWORD FileSize, ULONG_PTR ImageBase, ULONG_PTR AddressToConvert, bool AddressIsRVA, bool ReturnType) + //// + /// + // ConvertVAtoFileOffsetEx - converts virtual addresses to its physical counterpart. + // checks if PE file is valid and if memory is accessible + // Returns: converted physical address + // or NULL if conversion has failed. + // + ULONG_PTR ConvertVAtoFileOffsetEx( + ULONG_PTR FileMapVA, // [in] Pointer to the mapped file content. It's either StaticFileLoad function or Windows API for file mapping. + DWORD FileSize, // [in] Size of the mapped file. + ULONG_PTR ImageBase, // [in] ImageBase of the mapped file + ULONG_PTR AddressToConvert, // [in] Virtual address to convert to a physical address. + bool AddressIsRVA, // [in] true => AddressToConvert is relative virtual address + bool ReturnType // [in] Add the FileMapVA return value? + ) { auto found = mappedFiles.find(FileMapVA); if(found == mappedFiles.end()) __debugbreak(); //return 0; + if(!found->second.pe->IsValidPe()) __debugbreak(); //return 0; - auto offset = found->second.pe->ConvertRvaToOffset(uint32(AddressToConvert)); + + // Convert to RVA if needed + auto RVA_ToConvert = AddressIsRVA ? + AddressToConvert : + AddressToConvert - ImageBase; + + auto offset = found->second.pe->ConvertRvaToOffset( + uint32( RVA_ToConvert ) + ); + if (offset == INVALID_VALUE) return 0; - return ReturnType ? FileMapVA + offset : offset; } template From 9f16d365046757e65f7e67265ff6e3f73b7a31d6 Mon Sep 17 00:00:00 2001 From: cw2k <3834079+cw2k@users.noreply.github.com> Date: Tue, 3 Nov 2020 22:53:57 +0100 Subject: [PATCH 3/4] added handler for 'ReturnType' added handler for the parameter 'ReturnType' inConvertFileOffsetToVA(), ConvertVAtoFileOffset() and ConvertVAtoFileOffsetEx() --- TitanEngineEmulator/Emulator.h | 35 +++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/TitanEngineEmulator/Emulator.h b/TitanEngineEmulator/Emulator.h index 8df767c..7a424f6 100644 --- a/TitanEngineEmulator/Emulator.h +++ b/TitanEngineEmulator/Emulator.h @@ -567,21 +567,35 @@ public: mappedFiles.erase(found); return true; } - - ULONG_PTR ConvertFileOffsetToVA(ULONG_PTR FileMapVA, ULONG_PTR AddressToConvert, bool ReturnType) + //// + /// + // ConvertFileOffsetToVA - converts FileOffset to a virtual addresses + // checks if PE file is valid and if memory is accessible + // Returns: converted VA + // or NULL if conversion has failed. + // + ULONG_PTR ConvertFileOffsetToVA( + ULONG_PTR FileMapVA, // [in] Pointer to the mapped file content. It's either StaticFileLoad function or Windows API for file mapping. + ULONG_PTR AddressToConvert, // [in] physical address/file offset + bool ReturnType // [in] if true: add the FileMapVA to the return value + ) { auto found = mappedFiles.find(FileMapVA); - if(found == mappedFiles.end()) __debugbreak(); //return 0; if(!found->second.pe->IsValidPe()) __debugbreak(); //return 0; - auto offset = found->second.pe->ConvertOffsetToRva( uint32( AddressToConvert ) ); + // convert: FileOffset -> VA + auto offset = found->second.pe->ConvertOffsetToRva( + uint32( AddressToConvert ) + ); if (offset == INVALID_VALUE) - return 0; + return 0 + else + return ReturnType ? FileMapVA + offset : offset; } //// @@ -594,11 +608,11 @@ public: ULONG_PTR ConvertVAtoFileOffset( ULONG_PTR FileMapVA, // [in] Pointer to the mapped file content. It's either StaticFileLoad function or Windows API for file mapping. ULONG_PTR AddressToConvert, // [in] Virtual address to convert to a physical address. - bool ReturnType // [in] Add the FileMapVA return value? + bool ReturnType // [in] if true: add the FileMapVA to the return value ) { return ConvertVAtoFileOffsetEx( - FileMapVA ,0 ,0 , + FileMapVA ,0 ,0 , AddressToConvert, false, ReturnType ); } @@ -615,7 +629,7 @@ public: ULONG_PTR ImageBase, // [in] ImageBase of the mapped file ULONG_PTR AddressToConvert, // [in] Virtual address to convert to a physical address. bool AddressIsRVA, // [in] true => AddressToConvert is relative virtual address - bool ReturnType // [in] Add the FileMapVA return value? + bool ReturnType // [in] if true: add the FileMapVA to the return value ) { auto found = mappedFiles.find(FileMapVA); @@ -630,12 +644,15 @@ public: AddressToConvert : AddressToConvert - ImageBase; + // convert: VA -> FileOffset auto offset = found->second.pe->ConvertRvaToOffset( uint32( RVA_ToConvert ) ); if (offset == INVALID_VALUE) - return 0; + return 0 + else + return ReturnType ? FileMapVA + offset : offset; } template From 34b632311f041b1932b4b5435456e11b4507db3d Mon Sep 17 00:00:00 2001 From: cw2k <3834079+cw2k@users.noreply.github.com> Date: Tue, 3 Nov 2020 23:10:22 +0100 Subject: [PATCH 4/4] Added handler for AddressIsRVA & ReturnType --- StaticEngine/Emulator.h | 97 +++++++++++++++++++++++++++++++++-------- 1 file changed, 78 insertions(+), 19 deletions(-) diff --git a/StaticEngine/Emulator.h b/StaticEngine/Emulator.h index 31a349f..037db63 100644 --- a/StaticEngine/Emulator.h +++ b/StaticEngine/Emulator.h @@ -503,33 +503,92 @@ public: mappedFiles.erase(found); return true; } - - ULONG_PTR ConvertFileOffsetToVA(ULONG_PTR FileMapVA, ULONG_PTR AddressToConvert, bool ReturnType) + //// + /// + // ConvertFileOffsetToVA - converts FileOffset to a virtual addresses + // checks if PE file is valid and if memory is accessible + // Returns: converted VA + // or NULL if conversion has failed. + // + ULONG_PTR ConvertFileOffsetToVA( + ULONG_PTR FileMapVA, // [in] Pointer to the mapped file content. It's either StaticFileLoad function or Windows API for file mapping. + ULONG_PTR AddressToConvert, // [in] physical address/file offset + bool ReturnType // [in] if true: add the FileMapVA to the return value + ) { auto found = mappedFiles.find(FileMapVA); if (found == mappedFiles.end()) __debugbreak(); //return 0; + if (!found->second.pe->IsValidPe()) __debugbreak(); //return 0; - return found->second.pe->ConvertOffsetToRva(uint32(AddressToConvert)); - } - ULONG_PTR ConvertVAtoFileOffset(ULONG_PTR FileMapVA, ULONG_PTR AddressToConvert, bool ReturnType) - { - return ConvertVAtoFileOffsetEx(FileMapVA, 0, 0, AddressToConvert, false, ReturnType); - } + // convert: FileOffset -> VA + auto offset = found->second.pe->ConvertOffsetToRva( + uint32( AddressToConvert ) + ); - ULONG_PTR ConvertVAtoFileOffsetEx(ULONG_PTR FileMapVA, DWORD FileSize, ULONG_PTR ImageBase, ULONG_PTR AddressToConvert, bool AddressIsRVA, bool ReturnType) - { - auto found = mappedFiles.find(FileMapVA); - if (found == mappedFiles.end()) - __debugbreak(); //return 0; - if (!found->second.pe->IsValidPe()) - __debugbreak(); //return 0; - auto offset = found->second.pe->ConvertRvaToOffset(uint32(AddressToConvert)); if (offset == INVALID_VALUE) - return 0; - return ReturnType ? FileMapVA + offset : offset; + return 0 + else + return ReturnType ? FileMapVA + offset : offset; + } + + //// + /// + // ConvertVAtoFileOffset - converts virtual addresses to its physical counterpart. + // + // Returns: converted physical address + // or NULL if conversion has failed. + // + ULONG_PTR ConvertVAtoFileOffset( + ULONG_PTR FileMapVA, // [in] Pointer to the mapped file content. It's either StaticFileLoad function or Windows API for file mapping. + ULONG_PTR AddressToConvert, // [in] Virtual address to convert to a physical address. + bool ReturnType // [in] if true: add the FileMapVA to the return value + ) + { + return ConvertVAtoFileOffsetEx( + FileMapVA ,0 ,0 , + AddressToConvert, false, ReturnType ); + } + + //// + /// + // ConvertVAtoFileOffsetEx - converts virtual addresses to its physical counterpart. + // checks if PE file is valid and if memory is accessible + // Returns: converted physical address + // or NULL if conversion has failed. + // + ULONG_PTR ConvertVAtoFileOffsetEx( + ULONG_PTR FileMapVA, // [in] Pointer to the mapped file content. It's either StaticFileLoad function or Windows API for file mapping. + DWORD FileSize, // [in] Size of the mapped file. + ULONG_PTR ImageBase, // [in] ImageBase of the mapped file + ULONG_PTR AddressToConvert, // [in] Virtual address to convert to a physical address. + bool AddressIsRVA, // [in] true => AddressToConvert is relative virtual address + bool ReturnType // [in] if true: add the FileMapVA to the return value + ) + { + auto found = mappedFiles.find(FileMapVA); + if (found == mappedFiles.end()) + __debugbreak(); //return 0; + + if (!found->second.pe->IsValidPe()) + __debugbreak(); //return 0; + + // Convert to RVA if needed + auto RVA_ToConvert = AddressIsRVA ? + AddressToConvert : + AddressToConvert - ImageBase; + + // convert: VA -> FileOffset + auto offset = found->second.pe->ConvertRvaToOffset( + uint32( RVA_ToConvert ) + ); + + if (offset == INVALID_VALUE) + return 0 + else + return ReturnType ? FileMapVA + offset : offset; } template @@ -754,4 +813,4 @@ private: //variables PROCESS_INFORMATION* mAttachProcessInfo = nullptr; PROCESS_INFORMATION mProcessInfo; DEBUG_EVENT mDebugEvent; -}; \ No newline at end of file +};