Jump to content
Tuts 4 You

[Delphi] Add Section problems


steve10120

Recommended Posts

Hi. I've got a problem. I'm creating a fake signer, thats adding a new section to the PE, adds the sig, and a push/retn to go back to the OEP. Now, my problem is an odd one, while I've been building it I've been calling the function(s) via Form.Create event, and all is working perfectly, but now everything is ready I started to make the GUI and call via button click events, this is when I started running into problems. Just doesn't make sense to me, if it works via Form.Create should work anywhere else, no?

This is the add section function I'm using, I ported it from a VB version, I forget who that was by. Please excuse the mess I've changed all the read/write to copymem stuff in a vain attempt to fix it.

unit uAddSection;interfaceuses
Windows;type
TByteArray = array of Byte;function AddSection(szFileName:string; szNewSectionName:string; dwNewSectionSize:DWORD; dwNewSectionCharacteristics:DWORD):Boolean;implementationfunction FileToBytes(sPath:string; var bFile:TByteArray):Boolean;
var
hFile: THandle;
dSize: DWORD;
dRead: DWORD;
begin
Result := FALSE;
hFile := CreateFile(PChar(sPath), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
if hFile <> 0 then
begin
dSize := GetFileSize(hFile, nil);
SetFilePointer(hFile, 0, nil, FILE_BEGIN);
SetLength(bFile, dSize);
if ReadFile(hFile, bFile[0], dSize, dRead, nil) then
Result := TRUE;
CloseHandle(hFile);
end;
end;procedure BytesToFile(bData:TByteArray; sPath:string);
var
hFile: THandle;
dWritten: DWORD;
begin
hFile := CreateFile(PChar(sPath), GENERIC_WRITE, FILE_SHARE_WRITE, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if hFile <> 0 then
begin
SetFilePointer(hFile, 0, nil, FILE_BEGIN);
WriteFile(hFile, bData[0],Length(bData), dWritten, nil);
CloseHandle(hFile);
end;
end;function Align(dwValue:DWORD; dwAlign:DWORD):DWORD;
begin
if dwAlign <> 0 then
begin
if dwValue mod dwAlign <> 0 then
begin
Result := (dwValue + dwAlign) - (dwValue mod dwAlign);
Exit;
end;
end;
Result := dwValue;
end;function LastSectionRaw(Sections: array of TImageSectionHeader):DWORD;
var
i: integer;
Ret: DWORD;
begin
Ret := 0;
for i := Low(Sections) to High(Sections) do
begin
if Sections[i].SizeOfRawData + Sections[i].PointerToRawData > Ret then
Ret := Sections[i].SizeOfRawData + Sections[i].PointerToRawData;
end;
Result := Ret;
end;function LastSectionVirtual(Sections: array of TImageSectionHeader):DWORD;
var
i: integer;
Ret: DWORD;
begin
Ret := 0;
for i := Low(Sections) to High(Sections) do
begin
if Sections[i].Misc.VirtualSize + Sections[i].VirtualAddress > Ret then
Ret := Sections[i].Misc.VirtualSize + Sections[i].VirtualAddress;
end;
Result := Ret;
end;function AddSection(szFileName:string; szNewSectionName:string; dwNewSectionSize:DWORD; dwNewSectionCharacteristics:DWORD):Boolean;
var
hFile: DWORD;
x, i, k: integer;
IDH: TImageDosHeader;
INH: TImageNtHeaders;
Sections: array of TImageSectionHeader;
dwRead: DWORD;
bDataBuff: array of Byte;
bFile: TByteArray;
const
szError: string = 'Error';
begin
Result := FALSE;
if Length(szNewSectionName) > 1 then
begin
if Length(szNewSectionName) > 8 then
szNewSectionName := Copy(szNewSectionName, 1, 8); if FileToBytes(szFileName, bFile) then
begin
CopyMemory(@IDH, @bFile[0], 64);
if IDH.e_magic = IMAGE_DOS_SIGNATURE then
begin
CopyMemory(@INH, @bFile[IDH._lfanew], 248);
if INH.Signature = IMAGE_NT_SIGNATURE then
begin
k := INH.FileHeader.NumberOfSections;
SetLength(Sections, k);
x := IDH._lfanew + 24 + INH.FileHeader.SizeOfOptionalHeader;
for i := Low(Sections) to High(Sections) do
begin
CopyMemory(@Sections[i], @bFile[x], 40);
Inc(x, 40);
end;
if INH.OptionalHeader.SizeOfHeaders >= (x + 40) then
begin
Inc(INH.FileHeader.NumberOfSections, 1);
SetLength(Sections, INH.FileHeader.NumberOfSections); with Sections[INH.FileHeader.NumberOfSections] do
begin
CopyMemory(@Name[0], @szNewSectionName[1], 8);
Characteristics := dwNewSectionCharacteristics;
PointerToRawData := Align(LastSectionRaw(Sections), INH.OptionalHeader.FileAlignment);
SizeOfRawData := Align(dwNewSectionSize, INH.OptionalHeader.FileAlignment);
VirtualAddress := Align(LastSectionVirtual(Sections), INH.OptionalHeader.SectionAlignment);
Misc.VirtualSize := Align(dwNewSectionSize, INH.OptionalHeader.SectionAlignment);
end; INH.OptionalHeader.DataDirectory[11].VirtualAddress := 0;
INH.OptionalHeader.DataDirectory[11].Size := 0; Inc(INH.OptionalHeader.SizeOfImage, Sections[INH.FileHeader.NumberOfSections].Misc.VirtualSize); CopyMemory(@bFile[IDH._lfanew], @INH, 248); //SetFilePointer(hFile, IDH._lfanew, nil, FILE_BEGIN);
//WriteFile(hFile, INH, 248, dwRead, nil); CopyMemory(@bFile[x], @Sections[INH.FileHeader.NumberOfSections], 40); //SetFilePointer(hFile, x, nil, FILE_BEGIN);
//WriteFile(hFile, Sections[INH.FileHeader.NumberOfSections], 40, dwRead, nil); dwNewSectionSize := Align(dwNewSectionSize, INH.OptionalHeader.FileAlignment);
SetLength(bDataBuff, dwNewSectionSize);
SetLength(bFile, Length(bFile) + dwNewSectionSize);
CopyMemory(@bFile[Length(bFile)], @bDataBuff[0], dwNewSectionSize); //SetFilePointer(hFile, 0, nil, FILE_END);
//WriteFile(hFile, bDataBuff[0], dwNewSectionSize, dwRead, nil);
//CloseHandle(hFile);
BytesToFile(bFile, 'faked.exe');
Result := TRUE;
end;
end
else
MessageBox(0, PChar('Bad PE signature.'), PChar(szError), MB_ICONEXCLAMATION);
end
else
MessageBox(0, PChar('Bad MZ signature.'), PChar(szError), MB_ICONEXCLAMATION);
end
else
MessageBox(0, PChar('Error opening file.'), PChar(szError), MB_ICONEXCLAMATION);
end;
end;end.

The original without modifications, this one would error on the SetLength(bDataBuff, dwNewSectionSize) line.

unit uAddSection;interfaceuses
Windows;function AddSection(szFileName:string; szNewSectionName:string; dwNewSectionSize:DWORD; dwNewSectionCharacteristics:DWORD):Boolean;implementationfunction Align(dwValue:DWORD; dwAlign:DWORD):DWORD;
begin
if dwAlign <> 0 then
begin
if dwValue mod dwAlign <> 0 then
begin
Result := (dwValue + dwAlign) - (dwValue mod dwAlign);
Exit;
end;
end;
Result := dwValue;
end;function LastSectionRaw(Sections: array of TImageSectionHeader):DWORD;
var
i: integer;
Ret: DWORD;
begin
Ret := 0;
for i := Low(Sections) to High(Sections) do
begin
if Sections[i].SizeOfRawData + Sections[i].PointerToRawData > Ret then
Ret := Sections[i].SizeOfRawData + Sections[i].PointerToRawData;
end;
Result := Ret;
end;function LastSectionVirtual(Sections: array of TImageSectionHeader):DWORD;
var
i: integer;
Ret: DWORD;
begin
Ret := 0;
for i := Low(Sections) to High(Sections) do
begin
if Sections[i].Misc.VirtualSize + Sections[i].VirtualAddress > Ret then
Ret := Sections[i].Misc.VirtualSize + Sections[i].VirtualAddress;
end;
Result := Ret;
end;function AddSection(szFileName:string; szNewSectionName:string; dwNewSectionSize:DWORD; dwNewSectionCharacteristics:DWORD):Boolean;
var
hFile: DWORD;
x, i, k: integer;
IDH: TImageDosHeader;
INH: TImageNtHeaders;
Sections: array of TImageSectionHeader;
dwRead: DWORD;
bDataBuff: array of Byte;
const
szError: string = 'Error';
begin
Result := FALSE;
if Length(szNewSectionName) > 1 then
begin
if Length(szNewSectionName) > 8 then
szNewSectionName := Copy(szNewSectionName, 1, 8); hFile := CreateFile(PChar(szFileName), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
if hFile <> INVALID_HANDLE_VALUE then
begin
SetFilePointer(hFile, 0, nil, FILE_BEGIN);
ReadFile(hFile, IDH, 64, dwRead, nil);
if IDH.e_magic = IMAGE_DOS_SIGNATURE then
begin
SetFilePointer(hFile, IDH._lfanew, nil, FILE_BEGIN);
ReadFile(hFile, INH, 248, dwRead, nil);
if INH.Signature = IMAGE_NT_SIGNATURE then
begin
k := INH.FileHeader.NumberOfSections;
SetLength(Sections, k);
x := IDH._lfanew + 24 + INH.FileHeader.SizeOfOptionalHeader;
for i := Low(Sections) to High(Sections) do
begin
SetFilePointer(hFile, x, nil, FILE_BEGIN);
ReadFile(hFile, Sections[i], 40, dwRead, nil);
Inc(x, 40);
end;
if INH.OptionalHeader.SizeOfHeaders >= (x + 40) then
begin
Inc(INH.FileHeader.NumberOfSections, 1);
SetLength(Sections, INH.FileHeader.NumberOfSections); with Sections[INH.FileHeader.NumberOfSections] do
begin
CopyMemory(@Name[0], @szNewSectionName[1], 8);
Characteristics := dwNewSectionCharacteristics;
PointerToRawData := Align(LastSectionRaw(Sections), INH.OptionalHeader.FileAlignment);
SizeOfRawData := Align(dwNewSectionSize, INH.OptionalHeader.FileAlignment);
VirtualAddress := Align(LastSectionVirtual(Sections), INH.OptionalHeader.SectionAlignment);
Misc.VirtualSize := Align(dwNewSectionSize, INH.OptionalHeader.SectionAlignment);
end; INH.OptionalHeader.DataDirectory[11].VirtualAddress := 0;
INH.OptionalHeader.DataDirectory[11].Size := 0; Inc(INH.OptionalHeader.SizeOfImage, Sections[INH.FileHeader.NumberOfSections].Misc.VirtualSize); SetFilePointer(hFile, IDH._lfanew, nil, FILE_BEGIN);
WriteFile(hFile, INH, 248, dwRead, nil);
SetFilePointer(hFile, x, nil, FILE_BEGIN);
WriteFile(hFile, Sections[INH.FileHeader.NumberOfSections], 40, dwRead, nil); dwNewSectionSize := Align(dwNewSectionSize, INH.OptionalHeader.FileAlignment);
SetLength(bDataBuff, dwNewSectionSize); SetFilePointer(hFile, 0, nil, FILE_END);
WriteFile(hFile, bDataBuff[0], dwNewSectionSize, dwRead, nil);
CloseHandle(hFile);
Result := TRUE;
end;
end
else
MessageBox(0, PChar('Bad PE signature.'), PChar(szError), MB_ICONEXCLAMATION);
end
else
MessageBox(0, PChar('Bad MZ signature.'), PChar(szError), MB_ICONEXCLAMATION);
end
else
MessageBox(0, PChar('Error opening file.'), PChar(szError), MB_ICONEXCLAMATION);
end;
end;end.

Any suggestions would be appreciated.

Link to comment

This line must provide an error:

			WriteFile(hFile, Sections[INH.FileHeader.NumberOfSections], 40, dwRead, nil)

Why? Because you have declared this (i.e. a dynamic array):

Sections: array of TImageSectionHeader;

and then you have assigned this length:

			SetLength(Sections, INH.FileHeader.NumberOfSections);

So, you have got Sections as a dynamic array, and this kind of array ALWAYS uses the index range from [0..Length(array)-1].

The right line could be then:

			WriteFile(hFile, Sections[INH.FileHeader.NumberOfSections-1], 40, dwRead, nil)

Just test and let me know if it works fine now... ;)

Best regards

Nacho_dj

Link to comment

Thanks for the reply. I see what you mean there, but no after fixing that and a couple of other lines the error still occurs on SetLength(bDataBuff, dwNewSectionSize), dwNewSectionSize is the correct value too btw.

Link to comment

Yeah, there are more lines with a similar error. Please check the maximum value assigned to the index of dynamic arrays in every line using one of them...

Link to comment

Yep done that, is adding the section header fine. The error still occurring on SetLength(), really doesn't make sense to me.

function AddSection(szFileName:string; szNewSectionName:string; dwNewSectionSize:DWORD; dwNewSectionCharacteristics:DWORD):Boolean;
var
hFile: DWORD;
x, i, k: integer;
IDH: TImageDosHeader;
INH: TImageNtHeaders;
Sections: array of TImageSectionHeader;
dwRead: DWORD;
bDataBuff: array of Byte;
const
szError: string = 'Error';
begin
Result := FALSE;
if Length(szNewSectionName) > 1 then
begin
if Length(szNewSectionName) > 8 then
szNewSectionName := Copy(szNewSectionName, 1, 8); hFile := CreateFile(PChar(szFileName), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
if hFile <> INVALID_HANDLE_VALUE then
begin
SetFilePointer(hFile, 0, nil, FILE_BEGIN);
ReadFile(hFile, IDH, 64, dwRead, nil);
if IDH.e_magic = IMAGE_DOS_SIGNATURE then
begin
SetFilePointer(hFile, IDH._lfanew, nil, FILE_BEGIN);
ReadFile(hFile, INH, 248, dwRead, nil);
if INH.Signature = IMAGE_NT_SIGNATURE then
begin
k := INH.FileHeader.NumberOfSections;
SetLength(Sections, k);
x := IDH._lfanew + 24 + INH.FileHeader.SizeOfOptionalHeader;
for i := Low(Sections) to High(Sections) do
begin
SetFilePointer(hFile, x, nil, FILE_BEGIN);
ReadFile(hFile, Sections[i], 40, dwRead, nil);
Inc(x, 40);
end;
if INH.OptionalHeader.SizeOfHeaders >= (x + 40) then
begin
Inc(INH.FileHeader.NumberOfSections, 1);
//SetLength(Sections, INH.FileHeader.NumberOfSections - 1); with Sections[INH.FileHeader.NumberOfSections - 1] do
begin
CopyMemory(@Name[0], @szNewSectionName[1], 8);
Characteristics := dwNewSectionCharacteristics;
PointerToRawData := Align(LastSectionRaw(Sections), INH.OptionalHeader.FileAlignment);
SizeOfRawData := Align(dwNewSectionSize, INH.OptionalHeader.FileAlignment);
VirtualAddress := Align(LastSectionVirtual(Sections), INH.OptionalHeader.SectionAlignment);
Misc.VirtualSize := Align(dwNewSectionSize, INH.OptionalHeader.SectionAlignment);
end; INH.OptionalHeader.DataDirectory[11].VirtualAddress := 0;
INH.OptionalHeader.DataDirectory[11].Size := 0; Inc(INH.OptionalHeader.SizeOfImage, Sections[INH.FileHeader.NumberOfSections - 1].Misc.VirtualSize); SetFilePointer(hFile, IDH._lfanew, nil, FILE_BEGIN);
WriteFile(hFile, INH, 248, dwRead, nil);
SetFilePointer(hFile, x, nil, FILE_BEGIN);
WriteFile(hFile, Sections[INH.FileHeader.NumberOfSections - 1], 40, dwRead, nil); dwNewSectionSize := Align(dwNewSectionSize, INH.OptionalHeader.FileAlignment);
SetLength(bDataBuff, dwNewSectionSize); SetFilePointer(hFile, 0, nil, FILE_END);
WriteFile(hFile, bDataBuff[0], dwNewSectionSize, dwRead, nil);
CloseHandle(hFile);
Result := TRUE;
end;
end
else
MessageBox(0, PChar('Bad PE signature.'), PChar(szError), MB_ICONEXCLAMATION);
end
else
MessageBox(0, PChar('Bad MZ signature.'), PChar(szError), MB_ICONEXCLAMATION);
end
else
MessageBox(0, PChar('Error opening file.'), PChar(szError), MB_ICONEXCLAMATION);
end;
end;
Link to comment

This is buggy also:

			Inc(INH.FileHeader.NumberOfSections, 1);
//SetLength(Sections, INH.FileHeader.NumberOfSections - 1); with Sections[INH.FileHeader.NumberOfSections - 1] do

If you increment numberofsections and not increment length of array, you are getting an out of range in the last sentence...

Try to debug it with the debugger of Delphi, configuring some watches to see the values and length of the arrays taken...

Edited by Nacho_dj
Link to comment

Yeah, incrementing the value so when I write INH the value is correct, I commented out the second SetLength because the correct new size of array is set with SetLength(Sections, k). Its adding the section header, see the attached file, file is invalid of course tho because the bDataBuff hasn't been written to it. I have debugged with the Delphi debugger too, many times(thats how I know the final SetLength is error'ing), as far as I can tell all values are what they should be.

Oh, and I just did a quick test in the section loop, added SysUtils and msgbox'd IntToHex(ISH.Misc.VirtualSize, 8), and the thing worked without errors, remove SysUtils and the msgbox, and the error is back, very odd. :S

Faked.rar

Edited by steve10120
Link to comment

This is typical, when there is a pointer error in the code, it doesn't appear if you use a Messagebox... :wacko:

OK, I will give a watch to your code, by testing & debugging it, tomorrow I'll reply.

Best regards

Nacho_dj

Link to comment

Thanks alot. :)

Edit: Think I might have fixed it - thanks to your earlier comments, after checking the contents of the array in the debugger it was indeed wrong, I must have missed something last night.

HoundSign coming to a forum near you soon. :D

32Lite 0.03a -> Oleg Prokhorov

ACProtect 1.90g -> Risco software Inc.

ASPack 2.11d -> Alexey Solodovnikov

ASProtect 1.1 -> Alexey Solodovnikov

Borland C++ DLL Method 2

CodeCrypt 0.15B -> defiler

Crunch/PE Heuristic -> Bit-Arts

MASM32 / TASM32

Microsoft Visual Basic 5.0 / 6.0

Microsoft Visual C++

Microsoft Visual C++ 7.1 DLL

Microsoft Visual C++ Private Version 2

Neolite 2.0 -> Neoworx Inc.

PE Crypt 1.02 -> random, killa & acpizer

PE Lock NT 2.01 -> :MARQUiS:

PE Pack 0.99 -> ANAKiN

PESHiELD 0.2 / 0.2b / 0.2b2 -> ANAKiN

PEtite 2.x -> Ian Luck

PowerBasic 7.02

Shrinker 3.3 -> Blink Inc.

SVKP 1.11 -> Pavol Cerven

tElock 0.41x -> tE!

VBOX 4.2 MTE -> WeijunLi

XCR 0.12 -> X-Lock

X-PEOR 0.99b -> MadMax

yoda's cryptor 1.x / modified

Edited by steve10120
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...