program segments(section) Topic is solved
-
- Posts: 147
- Joined: 05 Nov 2016, 22:42
program segments(section)
I want to get the segment name of the program like the picture above. What should I do?
Re: program segments(section) Topic is solved
Hello Whynotregister.
That informartion is actually stored as ASCII encoded text inside the executable file. It can be isolated by following (calculating) the many offsets (including the offsets of offsets and so on) of information inside the PE file untill you reach the section table. The names of the sections can than be collected from there.
Below is an example on how to achieve this.
One thing to keep in mind is that if the executable in question is compressed or packed, the section names retrieved will belong to the packers code, not to the unpacked PE.
Feel free to ask any questions about the code above or the PE file format and structure if you would like to.
Best wishes.
That informartion is actually stored as ASCII encoded text inside the executable file. It can be isolated by following (calculating) the many offsets (including the offsets of offsets and so on) of information inside the PE file untill you reach the section table. The names of the sections can than be collected from there.
Below is an example on how to achieve this.
Code: Select all
FileSelectFile, SELECTED_FILE,,,Select the PE file you wish to obtain the sections header names from, Executable Files (*.exe)
BinRead(SELECTED_FILE, FILE_RAW_CONTENTS, 10000) ; BinRead 10Kb. No need to read even nearly as much, but just in case...
NUMBER_OF_DOS_HEADER_16_BYTE_BLOCKS := "0x" . SubStr(FILE_RAW_CONTENTS, 19, 2) . SubStr(FILE_RAW_CONTENTS, 17, 2)
DOS_HEADER_SIZE := 0x10 * NUMBER_OF_DOS_HEADER_16_BYTE_BLOCKS
PE_HEADER_OFFSET := "0x" . SubStr(FILE_RAW_CONTENTS, (DOS_HEADER_SIZE * 2) - 1, 2) . SubStr(FILE_RAW_CONTENTS, (DOS_HEADER_SIZE * 2) - 3, 2) . SubStr(FILE_RAW_CONTENTS, (DOS_HEADER_SIZE * 2) - 5, 2) . SubStr(FILE_RAW_CONTENTS, (DOS_HEADER_SIZE * 2) - 7, 2)
;This is the first info we need.
NUMBER_OF_SECTIONS := "0x" . SubStr(FILE_RAW_CONTENTS, (PE_HEADER_OFFSET * 2) + 15, 2) . SubStr(FILE_RAW_CONTENTS, (PE_HEADER_OFFSET * 2) + 13, 2)
SIZE_OF_IMAGE_OPTIONAL_HEADER := "0x" . SubStr(FILE_RAW_CONTENTS, (PE_HEADER_OFFSET * 2) + 43,2) . SubStr(FILE_RAW_CONTENTS, (PE_HEADER_OFFSET * 2) + 41,2)
; Loop below collects the second information we need (names of sections).
SECTION_NAMES := Object()
Loop % NUMBER_OF_SECTIONS
{
CURRENT_SECTION := A_Index
CURRENT_SECTION_NAME := ""
Loop 8
{
CURRENT_SECTION_NAME .= Chr( "0x" . SubStr(FILE_RAW_CONTENTS, (PE_HEADER_OFFSET * 2) + 49 + (SIZE_OF_IMAGE_OPTIONAL_HEADER * 2) + ((A_Index - 1) * 2) + ((CURRENT_SECTION - 1) * 80), 2) )
}
SECTION_NAMES[A_Index] := CURRENT_SECTION_NAME
}
Loop % NUMBER_OF_SECTIONS
{
MSGBOX % SECTION_NAMES[A_Index]
}
Return
;################################################;
; BinRead() By Laszlo (https://autohotkey.com/board/topic/4299-simple-binary-file-readwrite-functions/)
;################################################;
/* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BinRead ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
| - Open binary file
| - Read n bytes (n = 0: all)
| - From offset (offset < 0: counted from end)
| - Close file
| data (replaced) <- file[offset + 0..n-1]
| Return #bytes actually read
*/ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
BinRead(file, ByRef data, n=0, offset=0)
{
h := DllCall("CreateFile","Str",file,"Uint",0x80000000,"Uint",3,"UInt",0,"UInt",3,"Uint",0,"UInt",0)
IfEqual h,-1, SetEnv, ErrorLevel, -1
IfNotEqual ErrorLevel,0,Return,0 ; couldn't open the file
m = 0 ; seek to offset
IfLess offset,0, SetEnv,m,2
r := DllCall("SetFilePointerEx","Uint",h,"Int64",offset,"UInt *",p,"Int",m)
IfEqual r,0, SetEnv, ErrorLevel, -3
IfNotEqual ErrorLevel,0, {
t = %ErrorLevel% ; save ErrorLevel to be returned
DllCall("CloseHandle", "Uint", h)
ErrorLevel = %t% ; return seek error
Return 0
}
TotalRead = 0
data =
IfEqual n,0, SetEnv n,0xffffffff ; almost infinite
format = %A_FormatInteger% ; save original integer format
SetFormat Integer, Hex ; for converting bytes to hex
Loop %n%
{
result := DllCall("ReadFile","UInt",h,"UChar *",c,"UInt",1,"UInt *",Read,"UInt",0)
if (!result or Read < 1 or ErrorLevel)
break
TotalRead += Read ; count read
c += 0 ; convert to hex
StringTrimLeft c, c, 2 ; remove 0x
c = 0%c% ; pad left with 0
StringRight c, c, 2 ; always 2 digits
data = %data%%c% ; append 2 hex digits
}
IfNotEqual ErrorLevel,0, SetEnv,t,%ErrorLevel%
h := DllCall("CloseHandle", "Uint", h)
IfEqual h,-1, SetEnv, ErrorLevel, -2
IfNotEqual t,,SetEnv, ErrorLevel, %t%
SetFormat Integer, %format% ; restore original format
Totalread += 0 ; convert to original format
Return TotalRead
}
Return
Feel free to ask any questions about the code above or the PE file format and structure if you would like to.
Best wishes.
"What is suitable automation? Whatever saves your day for the greater matters."
Barcoder - Create QR Codes and other Barcodes using only Autohotkey !!
Archmage Gray - A fantasy shooter game fully coded in AutoHotkey
Barcoder - Create QR Codes and other Barcodes using only Autohotkey !!
Archmage Gray - A fantasy shooter game fully coded in AutoHotkey
-
- Posts: 147
- Joined: 05 Nov 2016, 22:42
Re: program segments(section)
Gio wrote:Hello Whynotregister.
That informartion is actually stored as ASCII encoded text inside the executable file. It can be isolated by following (calculating) the many offsets (including the offsets of offsets and so on) of information inside the PE file untill you reach the section table. The names of the sections can than be collected from there.
Below is an example on how to achieve this.
One thing to keep in mind is that if the executable in question is compressed or packed, the section names retrieved will belong to the packers code, not to the unpacked PE.Code: Select all
FileSelectFile, SELECTED_FILE,,,Select the PE file you wish to obtain the sections header names from, Executable Files (*.exe) BinRead(SELECTED_FILE, FILE_RAW_CONTENTS, 10000) ; BinRead 10Kb. No need to read even nearly as much, but just in case... NUMBER_OF_DOS_HEADER_16_BYTE_BLOCKS := "0x" . SubStr(FILE_RAW_CONTENTS, 19, 2) . SubStr(FILE_RAW_CONTENTS, 17, 2) DOS_HEADER_SIZE := 0x10 * NUMBER_OF_DOS_HEADER_16_BYTE_BLOCKS PE_HEADER_OFFSET := "0x" . SubStr(FILE_RAW_CONTENTS, (DOS_HEADER_SIZE * 2) - 1, 2) . SubStr(FILE_RAW_CONTENTS, (DOS_HEADER_SIZE * 2) - 3, 2) . SubStr(FILE_RAW_CONTENTS, (DOS_HEADER_SIZE * 2) - 5, 2) . SubStr(FILE_RAW_CONTENTS, (DOS_HEADER_SIZE * 2) - 7, 2) ;This is the first info we need. NUMBER_OF_SECTIONS := "0x" . SubStr(FILE_RAW_CONTENTS, (PE_HEADER_OFFSET * 2) + 15, 2) . SubStr(FILE_RAW_CONTENTS, (PE_HEADER_OFFSET * 2) + 13, 2) SIZE_OF_IMAGE_OPTIONAL_HEADER := "0x" . SubStr(FILE_RAW_CONTENTS, (PE_HEADER_OFFSET * 2) + 43,2) . SubStr(FILE_RAW_CONTENTS, (PE_HEADER_OFFSET * 2) + 41,2) ; Loop below collects the second information we need (names of sections). SECTION_NAMES := Object() Loop % NUMBER_OF_SECTIONS { CURRENT_SECTION := A_Index CURRENT_SECTION_NAME := "" Loop 8 { CURRENT_SECTION_NAME .= Chr( "0x" . SubStr(FILE_RAW_CONTENTS, (PE_HEADER_OFFSET * 2) + 49 + (SIZE_OF_IMAGE_OPTIONAL_HEADER * 2) + ((A_Index - 1) * 2) + ((CURRENT_SECTION - 1) * 80), 2) ) } SECTION_NAMES[A_Index] := CURRENT_SECTION_NAME } Loop % NUMBER_OF_SECTIONS { MSGBOX % SECTION_NAMES[A_Index] } Return ;################################################; ; BinRead() By Laszlo (https://autohotkey.com/board/topic/4299-simple-binary-file-readwrite-functions/) ;################################################; /* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BinRead ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | - Open binary file | - Read n bytes (n = 0: all) | - From offset (offset < 0: counted from end) | - Close file | data (replaced) <- file[offset + 0..n-1] | Return #bytes actually read */ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BinRead(file, ByRef data, n=0, offset=0) { h := DllCall("CreateFile","Str",file,"Uint",0x80000000,"Uint",3,"UInt",0,"UInt",3,"Uint",0,"UInt",0) IfEqual h,-1, SetEnv, ErrorLevel, -1 IfNotEqual ErrorLevel,0,Return,0 ; couldn't open the file m = 0 ; seek to offset IfLess offset,0, SetEnv,m,2 r := DllCall("SetFilePointerEx","Uint",h,"Int64",offset,"UInt *",p,"Int",m) IfEqual r,0, SetEnv, ErrorLevel, -3 IfNotEqual ErrorLevel,0, { t = %ErrorLevel% ; save ErrorLevel to be returned DllCall("CloseHandle", "Uint", h) ErrorLevel = %t% ; return seek error Return 0 } TotalRead = 0 data = IfEqual n,0, SetEnv n,0xffffffff ; almost infinite format = %A_FormatInteger% ; save original integer format SetFormat Integer, Hex ; for converting bytes to hex Loop %n% { result := DllCall("ReadFile","UInt",h,"UChar *",c,"UInt",1,"UInt *",Read,"UInt",0) if (!result or Read < 1 or ErrorLevel) break TotalRead += Read ; count read c += 0 ; convert to hex StringTrimLeft c, c, 2 ; remove 0x c = 0%c% ; pad left with 0 StringRight c, c, 2 ; always 2 digits data = %data%%c% ; append 2 hex digits } IfNotEqual ErrorLevel,0, SetEnv,t,%ErrorLevel% h := DllCall("CloseHandle", "Uint", h) IfEqual h,-1, SetEnv, ErrorLevel, -2 IfNotEqual t,,SetEnv, ErrorLevel, %t% SetFormat Integer, %format% ; restore original format Totalread += 0 ; convert to original format Return TotalRead } Return
Feel free to ask any questions about the code above or the PE file format and structure if you would like to.
Best wishes.
Thank you very much. It has helped a lot.
Who is online
Users browsing this forum: Aqualest, Google [Bot] and 329 guests