236 lines
7.2 KiB
ActionScript
236 lines
7.2 KiB
ActionScript
package
|
|
{
|
|
public class Elf
|
|
{
|
|
private const PT_DYNAMIC:uint = 2
|
|
private const PT_LOAD:uint = 1
|
|
private const PT_READ_EXEC:uint = 5
|
|
private const DT_SYMTAB:uint = 6
|
|
private const DT_STRTAB:uint = 5
|
|
private const DT_PLTGOT:uint = 3
|
|
|
|
private var e_ba:ExploitByteArray
|
|
// elf base address
|
|
public var base:uint = 0
|
|
// program header address
|
|
public var ph:uint = 0
|
|
// number of program headers
|
|
public var ph_size:uint = 0
|
|
// program header entry size
|
|
public var ph_esize:uint = 0
|
|
// DYNAMIC segment address
|
|
public var seg_dynamic:uint = 0
|
|
// DYNAMIC segment size
|
|
public var seg_dynamic_size:uint = 0
|
|
// CODE segment address
|
|
public var seg_exec:uint = 0
|
|
// CODE segment size
|
|
public var seg_exec_size:uint = 0
|
|
// .dynsyn section address
|
|
public var sec_dynsym:uint = 0
|
|
// .synstr section address
|
|
public var sec_dynstr:uint = 0
|
|
// .got.plt section address
|
|
public var sec_got_plt:uint = 0
|
|
|
|
public function Elf(ba:ExploitByteArray, addr:uint)
|
|
{
|
|
e_ba = ba
|
|
set_base(addr)
|
|
set_program_header()
|
|
set_program_header_size()
|
|
set_program_header_entry_size()
|
|
set_dynamic_segment()
|
|
set_exec_segment()
|
|
set_dynsym()
|
|
set_dynstr()
|
|
set_got_plt()
|
|
}
|
|
|
|
public function external_symbol(name:String):uint {
|
|
var entry:uint = 0
|
|
var st_name:uint = 0
|
|
var st_value:uint = 0
|
|
var st_size:uint = 0
|
|
var st_info:uint = 0
|
|
var st_other:uint = 0
|
|
var st_shndx:uint = 0
|
|
var st_string:String = ""
|
|
var got_plt_index:uint = 0
|
|
|
|
for(var i:uint = 0; i < 1000; i++) { // 1000 is just a limit
|
|
entry = sec_dynsym + 0x10 + (i * 0x10)
|
|
st_name = e_ba.read(entry)
|
|
st_value = e_ba.read(entry + 4)
|
|
st_info = e_ba.read(entry + 0xc, "byte")
|
|
st_string = e_ba.read_string(sec_dynstr + st_name)
|
|
if (st_string == name) {
|
|
return e_ba.read(sec_got_plt + 0xc + (got_plt_index * 4))
|
|
}
|
|
if (st_info != 0x11) {
|
|
got_plt_index++
|
|
}
|
|
}
|
|
throw new Error()
|
|
}
|
|
|
|
public function symbol(name:String):uint {
|
|
var entry:uint = 0
|
|
var st_name:uint = 0
|
|
var st_value:uint = 0
|
|
var st_size:uint = 0
|
|
var st_info:uint = 0
|
|
var st_other:uint = 0
|
|
var st_shndx:uint = 0
|
|
var st_string:String = ""
|
|
|
|
for(var i:uint = 0; i < 3000; i++) { // 3000 is just a limit
|
|
entry = sec_dynsym + 0x10 + (i * 0x10)
|
|
st_name = e_ba.read(entry)
|
|
st_value = e_ba.read(entry + 4)
|
|
st_info = e_ba.read(entry + 0xc, "byte")
|
|
st_string = e_ba.read_string(sec_dynstr + st_name)
|
|
if (st_string == name) {
|
|
return base + st_value
|
|
}
|
|
}
|
|
throw new Error()
|
|
}
|
|
|
|
|
|
public function gadget(gadget:String, hint:uint):uint
|
|
{
|
|
var value:uint = parseInt(gadget, 16)
|
|
var contents:uint = 0
|
|
for (var i:uint = 0; i < seg_exec_size - 4; i++) {
|
|
contents = e_ba.read(seg_exec + i)
|
|
if (hint == 0xffffffff && value == contents) {
|
|
return seg_exec + i
|
|
}
|
|
if (hint != 0xffffffff && value == (contents & hint)) {
|
|
return seg_exec + i
|
|
}
|
|
}
|
|
throw new Error()
|
|
}
|
|
|
|
private function set_base(addr:uint):void
|
|
{
|
|
addr &= 0xffff0000
|
|
while (true) {
|
|
if (e_ba.read(addr) == 0x464c457f) {
|
|
base = addr
|
|
return
|
|
}
|
|
addr -= 0x1000
|
|
}
|
|
|
|
throw new Error()
|
|
}
|
|
|
|
private function set_program_header():void
|
|
{
|
|
ph = base + e_ba.read(base + 0x1c)
|
|
}
|
|
|
|
private function set_program_header_size():void
|
|
{
|
|
ph_size = e_ba.read(base + 0x2c, "word")
|
|
}
|
|
|
|
private function set_program_header_entry_size():void
|
|
{
|
|
ph_esize = e_ba.read(base + 0x2a, "word")
|
|
}
|
|
|
|
private function set_dynamic_segment():void
|
|
{
|
|
var entry:uint = 0
|
|
var p_type:uint = 0
|
|
|
|
for (var i:uint = 0; i < ph_size; i++) {
|
|
entry = ph + (i * ph_esize)
|
|
p_type = e_ba.read(entry)
|
|
if (p_type == PT_DYNAMIC) {
|
|
seg_dynamic = base + e_ba.read(entry + 8)
|
|
seg_dynamic_size = e_ba.read(entry + 0x14)
|
|
return
|
|
}
|
|
}
|
|
|
|
throw new Error()
|
|
}
|
|
|
|
private function set_exec_segment():void
|
|
{
|
|
var entry:uint = 0
|
|
var p_type:uint = 0
|
|
var p_flags:uint = 0
|
|
|
|
for (var i:uint = 0; i < ph_size; i++) {
|
|
entry = ph + (i * ph_esize)
|
|
p_type = e_ba.read(entry)
|
|
p_flags = e_ba.read(entry + 0x18)
|
|
if (p_type == PT_LOAD && (p_flags & PT_READ_EXEC) == PT_READ_EXEC) {
|
|
seg_exec = base + e_ba.read(entry + 8)
|
|
seg_exec_size = e_ba.read(entry + 0x14)
|
|
return
|
|
}
|
|
}
|
|
|
|
throw new Error()
|
|
}
|
|
|
|
private function set_dynsym():void
|
|
{
|
|
var entry:uint = 0
|
|
var s_type:uint = 0
|
|
|
|
for (var i:uint = 0; i < seg_dynamic_size; i = i + 8) {
|
|
entry = seg_dynamic + i
|
|
s_type = e_ba.read(entry)
|
|
if (s_type == DT_SYMTAB) {
|
|
sec_dynsym = e_ba.read(entry + 4)
|
|
return
|
|
}
|
|
}
|
|
|
|
throw new Error()
|
|
}
|
|
|
|
private function set_dynstr():void
|
|
{
|
|
var entry:uint = 0
|
|
var s_type:uint = 0
|
|
|
|
for (var i:uint = 0; i < seg_dynamic_size; i = i + 8) {
|
|
entry = seg_dynamic + i
|
|
s_type = e_ba.read(entry)
|
|
if (s_type == DT_STRTAB) {
|
|
sec_dynstr = e_ba.read(entry + 4)
|
|
return
|
|
}
|
|
}
|
|
|
|
throw new Error()
|
|
}
|
|
|
|
private function set_got_plt():void
|
|
{
|
|
var entry:uint = 0
|
|
var s_type:uint = 0
|
|
|
|
for (var i:uint = 0; i < seg_dynamic_size; i = i + 8) {
|
|
entry = seg_dynamic + i
|
|
s_type = e_ba.read(entry)
|
|
if (s_type == DT_PLTGOT) {
|
|
sec_got_plt = e_ba.read(entry + 4)
|
|
return
|
|
}
|
|
}
|
|
|
|
throw new Error()
|
|
}
|
|
}
|
|
}
|