Skip to content

Commit cc34499

Browse files
fixup the HexEdit bug.
1 parent 37824da commit cc34499

18 files changed

+890
-41
lines changed

PEParser/PEParser.cpp

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ PEParser::PEParser(const wchar_t* path) :_path(path) {
3030

3131
PEParser::PEParser(void* base) {
3232
_address = reinterpret_cast<PUCHAR>(base);
33+
_moduleBase = (DWORD_PTR)base;
3334
CheckValidity();
3435
}
3536

@@ -82,6 +83,10 @@ int PEParser::GetSectionCount() const {
8283
return _fileHeader->NumberOfSections;
8384
}
8485

86+
void PEParser::SetSectionCount(WORD count) {
87+
_fileHeader->NumberOfSections = count;
88+
}
89+
8590
const IMAGE_SECTION_HEADER* PEParser::GetSectionHeader(ULONG section) const {
8691
if (!IsValid() || section >= _fileHeader->NumberOfSections)
8792
return nullptr;
@@ -107,6 +112,23 @@ const IMAGE_DOS_HEADER& PEParser::GetDosHeader() const {
107112
return *_dosHeader;
108113
}
109114

115+
BYTE* PEParser::GetDosStub() {
116+
BYTE* pDosStub = nullptr;
117+
118+
if (_dosHeader->e_lfanew > sizeof(IMAGE_DOS_HEADER)) {
119+
pDosStub = (BYTE*)((DWORD_PTR)_dosHeader + sizeof(IMAGE_DOS_HEADER));
120+
}
121+
else if (_dosHeader->e_lfanew < sizeof(IMAGE_DOS_HEADER)) {
122+
_dosHeader->e_lfanew = sizeof(IMAGE_DOS_HEADER);
123+
}
124+
125+
return pDosStub;
126+
}
127+
128+
IMAGE_NT_HEADERS64* PEParser::GetNtHeader() {
129+
return _ntHeader;
130+
}
131+
110132
void* PEParser::GetBaseAddress() const {
111133
return _address;
112134
}
@@ -262,6 +284,10 @@ void* PEParser::GetAddress(unsigned rva) const {
262284
return ::ImageRvaToVa(::ImageNtHeader(_address), _address, rva, nullptr);
263285
}
264286

287+
BYTE* PEParser::GetFileAddress(DWORD offset) {
288+
return _address + offset;
289+
}
290+
265291
SubsystemType PEParser::GetSubsystemType() const {
266292
if (IsPe64())
267293
return static_cast<SubsystemType>(GetOptionalHeader64().Subsystem);
@@ -307,6 +333,19 @@ unsigned PEParser::RvaToFileOffset(unsigned rva) const {
307333
return rva;
308334
}
309335

336+
DWORD_PTR PEParser::FileOffsetToRva(DWORD_PTR offset) {
337+
auto sections = _sections;
338+
for (int i = 0; i < GetSectionCount(); ++i) {
339+
if ((sections[i].PointerToRawData <= offset) &&
340+
((sections[i].PointerToRawData + sections[i].SizeOfRawData) > offset))
341+
{
342+
return ((offset - sections[i].PointerToRawData) + sections[i].VirtualAddress);
343+
}
344+
}
345+
346+
return 0;
347+
}
348+
310349
DWORD_PTR PEParser::RVAToRelativeOffset(DWORD_PTR rva) const {
311350
auto sections = _sections;
312351
for (int i = 0; i < GetSectionCount(); ++i) {
@@ -327,6 +366,19 @@ int PEParser::RVAToSectionIndex(DWORD_PTR rva) const {
327366
return -1;
328367
}
329368

369+
DWORD PEParser::GetSectionHeaderBasedSizeOfImage() {
370+
DWORD lastVirtualOffset = 0, lastVirtualSize = 0;
371+
372+
for (WORD i = 0; i < GetSectionCount(); i++) {
373+
if ((_sections[i].VirtualAddress + _sections[i].Misc.VirtualSize) > (lastVirtualOffset + lastVirtualSize)) {
374+
lastVirtualOffset = _sections[i].VirtualAddress;
375+
lastVirtualSize = _sections[i].Misc.VirtualSize;
376+
}
377+
}
378+
379+
return lastVirtualSize + lastVirtualOffset;
380+
}
381+
330382
bool PEParser::GetImportAddressTable() const {
331383
auto dir = GetDataDirectory(IMAGE_DIRECTORY_ENTRY_IAT);
332384
if (dir->Size == 0)
@@ -546,4 +598,136 @@ void PEParser::AlignAllSectionHeaders() {
546598

547599
newFileSize = sections[i].PointerToRawData + sections[i].SizeOfRawData;
548600
}
601+
}
602+
603+
void PEParser::FixPEHeader() {
604+
DWORD size = _dosHeader->e_lfanew + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER);
605+
606+
if (!IsPe64()) {
607+
_opt32->DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;
608+
_opt32->DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;
609+
610+
for (DWORD i = _opt32->NumberOfRvaAndSizes; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++) {
611+
_opt32->DataDirectory[i].Size = 0;
612+
_opt32->DataDirectory[i].VirtualAddress = 0;
613+
}
614+
_opt32->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
615+
_fileHeader->SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER32);
616+
617+
_opt32->SizeOfImage = GetSectionHeaderBasedSizeOfImage();
618+
619+
if (_moduleBase) {
620+
_opt32->ImageBase = _moduleBase;;
621+
}
622+
623+
_opt32->SizeOfHeaders = AlignValue(size + _ntHeader->FileHeader.SizeOfOptionalHeader
624+
+ GetSectionCount() * sizeof(IMAGE_SECTION_HEADER), _opt32->FileAlignment);
625+
}
626+
else {
627+
_opt64->DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;
628+
_opt64->DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;
629+
630+
for (DWORD i = _opt64->NumberOfRvaAndSizes; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++) {
631+
_opt64->DataDirectory[i].Size = 0;
632+
_opt64->DataDirectory[i].VirtualAddress = 0;
633+
}
634+
635+
_opt64->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
636+
_fileHeader->SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER64);
637+
638+
if (_moduleBase) {
639+
_opt64->ImageBase = _moduleBase;
640+
}
641+
642+
_opt64->SizeOfHeaders = AlignValue(size + _fileHeader->SizeOfOptionalHeader +
643+
+GetSectionCount() * sizeof(IMAGE_SECTION_HEADER), _opt64->FileAlignment);
644+
}
645+
646+
RemoveIATDirectory();
647+
}
648+
649+
void PEParser::RemoveIATDirectory() {
650+
DWORD searchAddress = 0;
651+
652+
if (!IsPe64()) {
653+
searchAddress = _opt32->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress;
654+
_opt32->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = 0;
655+
_opt32->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size = 0;
656+
}
657+
else {
658+
searchAddress = _opt64->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress;
659+
_opt64->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = 0;
660+
_opt64->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size = 0;
661+
}
662+
663+
if (searchAddress) {
664+
for (WORD i = 0; i < GetSectionCount(); i++) {
665+
if (_sections[i].VirtualAddress <= searchAddress &&
666+
(_sections[i].VirtualAddress + _sections[i].Misc.VirtualSize) > searchAddress) {
667+
_sections[i].Characteristics |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
668+
}
669+
}
670+
}
671+
}
672+
673+
DWORD PEParser::GetSectionHeaderBasedFileSize() {
674+
DWORD lastRawOffset = 0, lastRawSize = 0;
675+
676+
for (WORD i = 0; i < GetSectionCount(); i++) {
677+
auto section = _sections[i];
678+
if ((section.PointerToRawData + section.SizeOfRawData) > (lastRawOffset + lastRawSize))
679+
{
680+
lastRawOffset = section.PointerToRawData;
681+
lastRawSize = section.SizeOfRawData;
682+
}
683+
}
684+
685+
return lastRawSize + lastRawOffset;
686+
}
687+
688+
bool PEParser::AddNewLastSection(const char* pSectionName, DWORD sectionSize, BYTE* pSectionData) {
689+
size_t len = strlen(pSectionName);
690+
DWORD fileAlignment = 0, sectionAlignment = 0;
691+
PEFileSection peFileSection;
692+
693+
if (len > IMAGE_SIZEOF_SHORT_NAME) {
694+
return false;
695+
}
696+
697+
if (!IsPe64()) {
698+
fileAlignment = _opt32->FileAlignment;
699+
sectionAlignment = _opt32->SectionAlignment;
700+
}
701+
else {
702+
fileAlignment = _opt64->FileAlignment;
703+
sectionAlignment = _opt64->SectionAlignment;
704+
}
705+
706+
memcpy_s(peFileSection._sectionHeader.Name, IMAGE_SIZEOF_SHORT_NAME, pSectionName, len);
707+
708+
peFileSection._sectionHeader.SizeOfRawData = sectionSize;
709+
peFileSection._sectionHeader.Misc.VirtualSize = AlignValue(sectionSize, sectionAlignment);
710+
711+
peFileSection._sectionHeader.PointerToRawData = AlignValue(GetSectionHeaderBasedFileSize(), fileAlignment);
712+
peFileSection._sectionHeader.VirtualAddress = AlignValue(GetSectionHeaderBasedSizeOfImage(), sectionAlignment);
713+
714+
peFileSection._sectionHeader.Characteristics = IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ
715+
| IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_INITIALIZED_DATA;
716+
717+
peFileSection._normalSize = peFileSection._sectionHeader.SizeOfRawData;
718+
peFileSection._dataSize = peFileSection._sectionHeader.SizeOfRawData;
719+
720+
if (pSectionData == nullptr) {
721+
peFileSection._pData = new BYTE[peFileSection._sectionHeader.SizeOfRawData];
722+
ZeroMemory(peFileSection._pData, peFileSection._sectionHeader.SizeOfRawData);
723+
}
724+
else {
725+
peFileSection._pData = pSectionData;
726+
}
727+
728+
_PESections.push_back(peFileSection);
729+
730+
SetSectionCount(GetSectionCount() + 1);
731+
732+
return true;
549733
}

PEParser/PEParser.h

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,18 @@ struct ResourceInfo {
146146
bool IsId{ false };
147147
};
148148

149+
class PEFileSection {
150+
public:
151+
IMAGE_SECTION_HEADER _sectionHeader;
152+
BYTE* _pData = nullptr;
153+
DWORD _dataSize = 0;
154+
DWORD _normalSize = 0;
155+
156+
PEFileSection() {
157+
ZeroMemory(&_sectionHeader, sizeof(IMAGE_SECTION_HEADER));
158+
}
159+
};
160+
149161
struct RelocInfo {
150162
uint64_t address;
151163
uint16_t* item;
@@ -166,7 +178,10 @@ class PEParser {
166178
bool HasImports() const;
167179
bool IsSystemFile() const;
168180

181+
void FixPEHeader();
182+
169183
int GetSectionCount() const;
184+
void SetSectionCount(WORD count);
170185
const IMAGE_SECTION_HEADER* GetSectionHeader(ULONG section) const;
171186
const IMAGE_DATA_DIRECTORY* GetDataDirectory(int index) const;
172187
const IMAGE_DOS_HEADER& GetDosHeader() const;
@@ -176,6 +191,11 @@ class PEParser {
176191

177192
ULONGLONG GetImageBase() const;
178193

194+
void RemoveIATDirectory();
195+
196+
DWORD GetSectionHeaderBasedFileSize();
197+
DWORD GetSectionHeaderBasedSizeOfImage();
198+
179199
DWORD GetImageSize() const;
180200
DWORD GetHeadersSize() const;
181201
DWORD GetAddressOfEntryPoint() const;
@@ -200,6 +220,8 @@ class PEParser {
200220

201221
void* GetMemAddress(unsigned rva) const;
202222

223+
BYTE* GetFileAddress(DWORD offset);
224+
203225
SubsystemType GetSubsystemType() const;
204226

205227
IMAGE_OPTIONAL_HEADER64& GetOptionalHeader64() const {
@@ -228,15 +250,24 @@ class PEParser {
228250
DWORD_PTR RVAToRelativeOffset(DWORD_PTR rva) const;
229251
int RVAToSectionIndex(DWORD_PTR rva) const;
230252
IMAGE_SECTION_HEADER* GetSections();
253+
DWORD_PTR FileOffsetToRva(DWORD_PTR offset);
231254

232255
LARGE_INTEGER GetFileSize() const;
233256

234257
std::vector<RelocInfo> GetRelocs(void* imageBase);
235258
static void RelocateImageByDelta(std::vector<RelocInfo>& relocs, const uint64_t delta);
236259

260+
BYTE* GetDosStub();
261+
262+
IMAGE_NT_HEADERS64* GetNtHeader();
263+
264+
std::vector<PEFileSection> _PESections;
265+
237266
protected:
238267
static const DWORD _fileAlignmentConstant = 0x200;
239268

269+
bool AddNewLastSection(const char* pSectionName, DWORD sectionSize, BYTE* pSectionData);
270+
240271
private:
241272
bool IsObjectPe64() const;
242273
void CheckValidity();
@@ -245,12 +276,13 @@ class PEParser {
245276
//CString GetResourceName(void* data) const;
246277

247278
PBYTE _address{ nullptr };
279+
DWORD_PTR _moduleBase = 0;
248280
LARGE_INTEGER _fileSize{ 0 };
249281
HMODULE _module{ nullptr };
250282
HANDLE _hMemMap{ nullptr };
251283
HANDLE _hFile{ INVALID_HANDLE_VALUE };
252284
IMAGE_DOS_HEADER* _dosHeader = nullptr;
253-
IMAGE_NT_HEADERS64* _ntHeader=nullptr;
285+
IMAGE_NT_HEADERS64* _ntHeader = nullptr;
254286
IMAGE_FILE_HEADER* _fileHeader = nullptr;
255287
IMAGE_SECTION_HEADER* _sections = nullptr;
256288
IMAGE_OPTIONAL_HEADER32* _opt32{ nullptr };

WinArk/DPCTimerTable.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,14 @@ LRESULT CDpcTimerTable::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL&
1010
return 0;
1111
}
1212

13+
LRESULT CDpcTimerTable::OnEraseBackground(UINT, WPARAM wParam, LPARAM, BOOL&) {
14+
return 1;
15+
}
16+
1317
LRESULT CDpcTimerTable::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lparam, BOOL& /*bHandled*/) {
1418
return 0;
1519
}
20+
1621
LRESULT CDpcTimerTable::OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) {
1722
PaintTable(m_hWnd);
1823
return 0;
@@ -47,15 +52,19 @@ LRESULT CDpcTimerTable::OnMouseWheel(UINT uMsg, WPARAM wParam, LPARAM lParam, BO
4752
int zDelta = GET_WHEEL_DELTA_WPARAM(wParam);
4853
return Tablefunction(m_hWnd, WM_VSCROLL, zDelta >= 0 ? 0 : 1, wParam);
4954
}
55+
5056
LRESULT CDpcTimerTable::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) {
5157
return Tablefunction(m_hWnd, uMsg, wParam, lParam);
5258
}
59+
5360
LRESULT CDpcTimerTable::OnLBtnDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) {
5461
return Tablefunction(m_hWnd, uMsg, wParam, lParam);
5562
}
63+
5664
LRESULT CDpcTimerTable::OnLBtnUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) {
5765
return Tablefunction(m_hWnd, uMsg, wParam, lParam);
5866
}
67+
5968
LRESULT CDpcTimerTable::OnRBtnDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) {
6069
CMenu menu;
6170
CMenuHandle hSubMenu;
@@ -73,6 +82,7 @@ LRESULT CDpcTimerTable::OnRBtnDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL
7382

7483
return 0;
7584
}
85+
7686
LRESULT CDpcTimerTable::OnUserSts(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) {
7787
return Tablefunction(m_hWnd, uMsg, wParam, lParam);
7888
}
@@ -129,7 +139,7 @@ int CDpcTimerTable::ParseTableEntry(CString& s, char& mask, int& select, std::sh
129139
break;
130140

131141
case Column::DueTime:
132-
s.Format(L"0x%x", info->DueTime);
142+
s.Format(L"0x%x", info->DueTime.QuadPart);
133143
break;
134144
}
135145
return s.GetLength();
@@ -142,7 +152,6 @@ void CDpcTimerTable::Refresh() {
142152
ULONG size = SymbolHelper::GetKernelStructSize("_KTIMER_TABLE_ENTRY");
143153
KernelTimerData data;
144154
if (size != 0) {
145-
146155
ULONG entryCount = memberSize / size;
147156
data.entriesOffset = SymbolHelper::GetKernelStructMemberOffset("_KTIMER_TABLE", "TimerEntries");
148157
data.maxEntryCount = entryCount;

WinArk/DPCTimerTable.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class CDpcTimerTable :
2121
MESSAGE_HANDLER(WM_USER_VABS, OnUserVabs)
2222
MESSAGE_HANDLER(WM_USER_VREL, OnUserVrel)
2323
MESSAGE_HANDLER(WM_USER_CHGS, OnUserChgs)
24+
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
2425
MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel)
2526
MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
2627
MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLBtnDown)
@@ -56,6 +57,7 @@ class CDpcTimerTable :
5657
LRESULT OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/);
5758
LRESULT OnSysKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/);
5859
LRESULT OnGetDlgCode(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
60+
LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
5961

6062
LRESULT OnRefresh(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
6163

0 commit comments

Comments
 (0)