steve10120 Posted June 28, 2009 Posted June 28, 2009 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;varhFile: 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);varhFile: 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.
Nacho_dj Posted June 28, 2009 Posted June 28, 2009 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
steve10120 Posted June 28, 2009 Author Posted June 28, 2009 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.
Nacho_dj Posted June 28, 2009 Posted June 28, 2009 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...
steve10120 Posted June 28, 2009 Author Posted June 28, 2009 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;
Nacho_dj Posted June 28, 2009 Posted June 28, 2009 (edited) This is buggy also: Inc(INH.FileHeader.NumberOfSections, 1); //SetLength(Sections, INH.FileHeader.NumberOfSections - 1); with Sections[INH.FileHeader.NumberOfSections - 1] doIf 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 June 28, 2009 by Nacho_dj
steve10120 Posted June 28, 2009 Author Posted June 28, 2009 (edited) 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. :SFaked.rar Edited June 28, 2009 by steve10120
Nacho_dj Posted June 28, 2009 Posted June 28, 2009 This is typical, when there is a pointer error in the code, it doesn't appear if you use a Messagebox... OK, I will give a watch to your code, by testing & debugging it, tomorrow I'll reply. Best regards Nacho_dj
steve10120 Posted June 28, 2009 Author Posted June 28, 2009 (edited) 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. 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 June 29, 2009 by steve10120
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now