157 lines
4.0 KiB
ActionScript
157 lines
4.0 KiB
ActionScript
|
package
|
||
|
{
|
||
|
import flash.utils.ByteArray;
|
||
|
|
||
|
public class PE32
|
||
|
{
|
||
|
private var m:Memory;
|
||
|
|
||
|
public var base:uint;
|
||
|
public var dos_header:uint;
|
||
|
public var nt_header:uint;
|
||
|
public var file_header:uint;
|
||
|
public var opt_header:uint;
|
||
|
|
||
|
private function FindBase(ptr:uint):uint {
|
||
|
ptr = ptr & 0xffff0000;
|
||
|
var dword:uint = m.read_dword(ptr);
|
||
|
|
||
|
while ((dword & 0xffff) != 0x5a4d) {
|
||
|
ptr -= 0x10000;
|
||
|
dword = m.read_dword(ptr);
|
||
|
}
|
||
|
|
||
|
return ptr;
|
||
|
}
|
||
|
|
||
|
public function ParseHeaders():void {
|
||
|
dos_header = base;
|
||
|
var e_lfanew:uint = m.read_dword(dos_header + 60);
|
||
|
|
||
|
nt_header = dos_header + e_lfanew;
|
||
|
var nt_magic:uint = m.read_dword(nt_header);
|
||
|
if (nt_magic != 0x00004550) {
|
||
|
dos_header = 0;
|
||
|
nt_header = 0;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
file_header = nt_header + 4;
|
||
|
var machine:uint = m.read_dword(file_header);
|
||
|
if ((machine & 0xffff) != 0x014c) {
|
||
|
dos_header = 0;
|
||
|
nt_header = 0;
|
||
|
file_header = 0;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
opt_header = nt_header + 24;
|
||
|
var opt_magic:uint = m.read_dword(opt_header);
|
||
|
if ((opt_magic & 0xffff) != 0x10b) {
|
||
|
dos_header = 0;
|
||
|
nt_header = 0;
|
||
|
file_header = 0;
|
||
|
opt_header = 0;
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function GetImport(mod_name:String, fun_name:String):uint {
|
||
|
if (base == 0 || dos_header == 0) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
var data_directory:uint = opt_header + 96;
|
||
|
|
||
|
var import_dir:uint = data_directory + 8;
|
||
|
var import_rva:uint = m.read_dword(import_dir);
|
||
|
var import_size:uint = m.read_dword(import_dir + 4);
|
||
|
if (import_size == 0) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
var import_descriptor:uint = base + import_rva;
|
||
|
var orig_first_thunk:uint = m.read_dword(import_descriptor);
|
||
|
while (orig_first_thunk != 0) {
|
||
|
|
||
|
var module_name_ptr:uint =
|
||
|
dos_header + m.read_dword(import_descriptor + 12);
|
||
|
|
||
|
if (module_name_ptr != 0) {
|
||
|
var module_name:String = m.read_string(module_name_ptr);
|
||
|
if (module_name == mod_name) {
|
||
|
orig_first_thunk += dos_header;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
import_descriptor += (5 * 4);
|
||
|
orig_first_thunk = m.read_dword(import_descriptor);
|
||
|
}
|
||
|
|
||
|
var first_thunk:uint = dos_header + m.read_dword(import_descriptor + 16);
|
||
|
var thunk:uint = orig_first_thunk;
|
||
|
var import_by_name_rva:uint = m.read_dword(thunk);
|
||
|
while (import_by_name_rva != 0) {
|
||
|
var function_name_ptr:uint = dos_header + import_by_name_rva + 2;
|
||
|
|
||
|
var function_name:String = m.read_string(function_name_ptr);
|
||
|
if (function_name == fun_name) {
|
||
|
return m.read_dword(first_thunk);
|
||
|
}
|
||
|
|
||
|
thunk += 4;
|
||
|
first_thunk += 4;
|
||
|
import_by_name_rva = m.read_dword(thunk);
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
public function GetGadget(gadget:ByteArray):uint {
|
||
|
var opt_header_size:uint = m.read_dword(file_header + 16) & 0xffff;
|
||
|
var section_count:uint = (m.read_dword(file_header) >> 16) & 0xffff;
|
||
|
var section_header:uint = opt_header + opt_header_size;
|
||
|
|
||
|
for (var i:uint = 0; i < section_count; ++i) {
|
||
|
var characteristics:uint = m.read_dword(section_header + (9 * 4));
|
||
|
|
||
|
if ((characteristics & 0xe0000000) == 0x60000000) {
|
||
|
// this section is read/execute, so scan for gadget
|
||
|
|
||
|
var section_rva:uint = m.read_dword(section_header + 12);
|
||
|
var section_size:uint = m.read_dword(section_header + 16);
|
||
|
var section_base:uint = base + section_rva;
|
||
|
var section:ByteArray = new ByteArray();
|
||
|
section.endian = "littleEndian";
|
||
|
section.length = section_size;
|
||
|
|
||
|
for (var j:uint = 0; j < section_size; j += 4) {
|
||
|
section.writeUnsignedInt(
|
||
|
m.read_dword(section_base + j));
|
||
|
}
|
||
|
|
||
|
for (j = 0; j < section_size; j += 1) {
|
||
|
section.position = j;
|
||
|
gadget.position = 0;
|
||
|
while (section.readByte() == gadget.readByte()) {
|
||
|
if (gadget.position == gadget.length) {
|
||
|
return section_base + j;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
section_header += 10 * 5;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
public function PE32(memory:Memory, ptr:uint) {
|
||
|
m = memory;
|
||
|
base = FindBase(ptr);
|
||
|
ParseHeaders();
|
||
|
}
|
||
|
}
|
||
|
}
|