update shellcode
- shellcode correctly passes arguments to main - shellcode deals with __bss section in __DATA - remove hardcoded values
This commit is contained in:
parent
693c2b6c95
commit
a2f9ca82e7
@ -355,6 +355,8 @@ func (mc *MachoContext) removeBindSymbolsLegacy() {
|
|||||||
|
|
||||||
func (mc *MachoContext) ReworkForObjc() {
|
func (mc *MachoContext) ReworkForObjc() {
|
||||||
text_start := 0
|
text_start := 0
|
||||||
|
data_end := 0
|
||||||
|
lc_main_offset := int64(0)
|
||||||
|
|
||||||
ptr := int64(0)
|
ptr := int64(0)
|
||||||
if mc.Is64bit() {
|
if mc.Is64bit() {
|
||||||
@ -364,6 +366,11 @@ func (mc *MachoContext) ReworkForObjc() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, cmd := range mc.commands {
|
for _, cmd := range mc.commands {
|
||||||
|
if cmd.Cmd() == LC_MAIN {
|
||||||
|
lc_main_offset = ptr + 8
|
||||||
|
ptr += int64(cmd.Cmdsize())
|
||||||
|
continue
|
||||||
|
}
|
||||||
if cmd.Cmd() != LC_SEGMENT_64 {
|
if cmd.Cmd() != LC_SEGMENT_64 {
|
||||||
ptr += int64(cmd.Cmdsize())
|
ptr += int64(cmd.Cmdsize())
|
||||||
continue
|
continue
|
||||||
@ -371,11 +378,17 @@ func (mc *MachoContext) ReworkForObjc() {
|
|||||||
var segment = cmd.(*Segment64)
|
var segment = cmd.(*Segment64)
|
||||||
|
|
||||||
if bytes.Compare(bytes.Trim(segment.SegName(), "\x00"), []byte("__TEXT")) == 0 {
|
if bytes.Compare(bytes.Trim(segment.SegName(), "\x00"), []byte("__TEXT")) == 0 {
|
||||||
|
section_ptr := ptr + 0x40 + 8
|
||||||
for _, section := range segment.Sections() {
|
for _, section := range segment.Sections() {
|
||||||
if bytes.Compare(bytes.Trim(section.SectName(), "\x00"), []byte("__text")) == 0 {
|
if bytes.Compare(bytes.Trim(section.SectName(), "\x00"), []byte("__text")) == 0 {
|
||||||
text_start = int(section.Offset())
|
text_start = int(section.Offset())
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
if bytes.Compare(bytes.Trim(section.SectName(), "\x00"), []byte("__init_offsets")) == 0 {
|
||||||
|
// mc.file.WriteAt([]byte("__init_offsetx"), section_ptr)
|
||||||
|
// edit flags to not S_MOD_INIT_FUNC
|
||||||
|
mc.file.WriteAt([]byte{0, 0, 0, 0}, section_ptr + 0x40)
|
||||||
|
}
|
||||||
|
section_ptr += 16 * 2 + 8 * 2 + 4 * 8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if bytes.Compare(bytes.Trim(segment.SegName(), "\x00"), []byte("__DATA_CONST")) == 0 {
|
if bytes.Compare(bytes.Trim(segment.SegName(), "\x00"), []byte("__DATA_CONST")) == 0 {
|
||||||
@ -391,11 +404,18 @@ func (mc *MachoContext) ReworkForObjc() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if bytes.Compare(bytes.Trim(segment.SegName(), "\x00"), []byte("__DATA")) == 0 {
|
if bytes.Compare(bytes.Trim(segment.SegName(), "\x00"), []byte("__DATA")) == 0 {
|
||||||
// section_ptr := ptr + 0x40 + 8
|
|
||||||
// for _, section := range segment.Sections() {
|
|
||||||
// section_ptr += 16 * 2 + 8 * 2 + 4 * 8
|
|
||||||
// }
|
|
||||||
// end of __DATA segment, should have enough space for a pointer
|
// end of __DATA segment, should have enough space for a pointer
|
||||||
|
|
||||||
|
// __bss section is dynamically allocated at the end to or something, hmmge
|
||||||
|
// assume that it order correctly, which it should if compiled and not modified
|
||||||
|
sections := segment.Sections()
|
||||||
|
last := sections[len(sections) - 1]
|
||||||
|
data_end = int(last.Offset()) + int(last.Size())
|
||||||
|
|
||||||
|
if (last.Offset() == 0) {
|
||||||
|
before_last := sections[len(sections) - 2]
|
||||||
|
data_end += int(before_last.Offset()) + int(before_last.Size())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ptr += int64(cmd.Cmdsize())
|
ptr += int64(cmd.Cmdsize())
|
||||||
}
|
}
|
||||||
@ -405,50 +425,63 @@ func (mc *MachoContext) ReworkForObjc() {
|
|||||||
// its physical size is still a page
|
// its physical size is still a page
|
||||||
// mc.file.WriteAt([]byte{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7}, int64(0x81d8))
|
// mc.file.WriteAt([]byte{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7}, int64(0x81d8))
|
||||||
|
|
||||||
ins_size_byte := 4
|
// we use 2 registers, x8 x9
|
||||||
x8_value_offset := text_start - (ins_size_byte * 17) + (ins_size_byte * 2)
|
// stack values:
|
||||||
main_offset := mc.entryoff
|
// [ return address, header, argc, argv, env, apple ]
|
||||||
|
// we need to store the return address, and parameters passed to main
|
||||||
|
// we also store our header address to not calculate many times
|
||||||
|
|
||||||
movz_x8_value_offset := uint32(uint32(x8_value_offset)<<5 | uint32(0x694)<<21 | uint32(0x09))
|
/*
|
||||||
movz_main_offset := uint32(uint32(main_offset)<<5 | uint32(0x694)<<21 | uint32(0x09))
|
adr x8, 0
|
||||||
|
sub sp, sp, #0x30
|
||||||
|
str x30, [sp]
|
||||||
|
movz x9, #0x3d68 ; offset at this point
|
||||||
|
sub x8, x8, x9
|
||||||
|
str x8, [sp, #0x8]
|
||||||
|
str x0, [sp, #0x10]
|
||||||
|
str x1, [sp, #0x18]
|
||||||
|
str x2, [sp, #0x20]
|
||||||
|
str x3, [sp, #0x28]
|
||||||
|
|
||||||
fmt.Printf("// x8_value_offset=%x\n", x8_value_offset)
|
movz x9, #0x81d8 ; offset to end of __DATA
|
||||||
fmt.Printf("// main_offset=%x\n", main_offset)
|
add x9, x8, x9
|
||||||
fmt.Printf("// x8_value_offset=%x\n", movz_x8_value_offset)
|
ldr x9, [x9]
|
||||||
fmt.Printf("// main_offset=%x\n", movz_main_offset)
|
blr x9
|
||||||
|
ldr x8, [sp, #0x8]
|
||||||
// sub sp, sp, #0x10
|
ldr x0, [sp, #0x10]
|
||||||
// str x30, [sp]
|
ldr x1, [sp, #0x18]
|
||||||
// adr x8, 0
|
ldr x2, [sp, #0x20]
|
||||||
// movz x9, #0x3d68 ; offset at this point
|
ldr x3, [sp, #0x28]
|
||||||
// sub x8, x8, x9
|
movz x9, #0x3e3c ; offset to original main
|
||||||
// str x8, [sp, #8]
|
add x9, x8, x9
|
||||||
// movz x9, #0x81d8
|
blr x9
|
||||||
// add x9, x8, x9
|
ldr x30, [sp]
|
||||||
// ldr x9, [x9]
|
add sp, sp, #0x10
|
||||||
// blr x9
|
ret
|
||||||
// ldr x8, [sp, #8]
|
*/
|
||||||
// movz x9, #0x3e3c ; offset to original main
|
|
||||||
// add x9, x8, x9
|
|
||||||
// blr x9
|
|
||||||
// ldr x30, [sp]
|
|
||||||
// add sp, sp, #0x10
|
|
||||||
// ret
|
|
||||||
|
|
||||||
// TODO: fix to work with offset larger than 0xffff
|
// TODO: fix to work with offset larger than 0xffff
|
||||||
shellcode := []uint32{
|
shellcode := []uint32{
|
||||||
0xD10043FF,
|
|
||||||
0xF90003FE,
|
|
||||||
0x10000008,
|
0x10000008,
|
||||||
movz_x8_value_offset,
|
0xD100C3FF,
|
||||||
|
0xF90003FE,
|
||||||
|
0, // movz_shellcode_offset,
|
||||||
0xCB090108,
|
0xCB090108,
|
||||||
0xF90007E8,
|
0xF90007E8,
|
||||||
0xD2903B09,
|
0xF9000BE0,
|
||||||
|
0xF9000FE1,
|
||||||
|
0xF90013E2,
|
||||||
|
0xF90017E3,
|
||||||
|
0, // movz_data_end_offset,
|
||||||
0x8B090109,
|
0x8B090109,
|
||||||
0xF9400129,
|
0xF9400129,
|
||||||
0xD63F0120,
|
0xD63F0120,
|
||||||
0xF94007E8,
|
0xF94007E8,
|
||||||
movz_main_offset,
|
0xF9400BE0,
|
||||||
|
0xF9400FE1,
|
||||||
|
0xF94013E2,
|
||||||
|
0xF94017E3,
|
||||||
|
0, // movz_main_offset,
|
||||||
0x8B090109,
|
0x8B090109,
|
||||||
0xD63F0120,
|
0xD63F0120,
|
||||||
0xF94003FE,
|
0xF94003FE,
|
||||||
@ -456,12 +489,36 @@ func (mc *MachoContext) ReworkForObjc() {
|
|||||||
0xD65F03C0,
|
0xD65F03C0,
|
||||||
}
|
}
|
||||||
|
|
||||||
offset := int64(0x3da4 - len(shellcode) * 4)
|
ins_size_byte := 4
|
||||||
|
shellcode_offset := text_start - (ins_size_byte * len(shellcode))
|
||||||
|
main_offset := int(mc.entryoff)
|
||||||
|
|
||||||
|
encode_movz := func(v int) uint32 {
|
||||||
|
return uint32(uint32(v)<<5 | uint32(0x694)<<21 | uint32(0x09))
|
||||||
|
}
|
||||||
|
|
||||||
|
movz_shellcode_offset := encode_movz(shellcode_offset)
|
||||||
|
movz_main_offset := encode_movz(main_offset)
|
||||||
|
movz_data_end_offset := encode_movz(data_end)
|
||||||
|
|
||||||
|
shellcode[3] = movz_shellcode_offset
|
||||||
|
shellcode[10] = movz_data_end_offset
|
||||||
|
shellcode[19] = movz_main_offset
|
||||||
|
|
||||||
|
fmt.Printf("// shellcode_offset=%x\n", shellcode_offset)
|
||||||
|
fmt.Printf("// main_offset=%x\n", main_offset)
|
||||||
|
fmt.Printf("// data_end=%x\n", data_end)
|
||||||
|
fmt.Printf("// movz_shellcode_offset=%x\n", movz_shellcode_offset)
|
||||||
|
fmt.Printf("// movz_main_offset=%x\n", movz_main_offset)
|
||||||
|
fmt.Printf("// movz_data_end_offset=%x\n", movz_data_end_offset)
|
||||||
|
fmt.Printf("// lc_main_offset=%x\n", lc_main_offset)
|
||||||
|
|
||||||
|
offset := int64(shellcode_offset)
|
||||||
{
|
{
|
||||||
// fix main to point to our newly created shellcode
|
// fix main to point to our newly created shellcode
|
||||||
bs := make([]byte, 8)
|
bs := make([]byte, 8)
|
||||||
mc.byteorder.PutUint64(bs, uint64(offset))
|
mc.byteorder.PutUint64(bs, uint64(offset))
|
||||||
mc.file.WriteAt(bs, int64(0x870))
|
mc.file.WriteAt(bs, int64(lc_main_offset))
|
||||||
}
|
}
|
||||||
|
|
||||||
bs := make([]byte, 4)
|
bs := make([]byte, 4)
|
||||||
|
Loading…
Reference in New Issue
Block a user