| #include <stdio.h> |
| #include <signal.h> |
| #include <unistd.h> |
| #include <string.h> |
| |
| double func_over_signal_thrower (double, float, const char *); |
| int signal_thrower (int); |
| void handler (int); |
| |
| int func_over_mov_imm32_addr_in_prologue (int); |
| int mov_imm32_reg_in_prologue (int); |
| int func_under_mov_imm32_reg_in_prologue (int); |
| |
| double func_over_cmpl_in_prologue (double, float); |
| int cmpl_in_prologue (void); |
| int func_under_cmpl_in_prologue (int); |
| |
| char *func_over_objc_msgForward_pattern (char *); |
| int objc_msgForward_pattern (int); |
| int func_under_objc_msgForward_pattern (int); |
| |
| main (int argc, char **argv, char **envp) |
| { |
| int ret; |
| char *sret; |
| |
| ret = func_over_signal_thrower (argc * 5.2, argc * 9999.33, argv[0]); |
| printf ("%d\n", ret); |
| |
| ret = func_over_mov_imm32_addr_in_prologue (argc * 2); |
| printf ("%d\n", ret); |
| |
| ret = func_over_cmpl_in_prologue (5, 10); |
| printf ("%d\n", ret); |
| |
| char buf [80]; |
| strcpy (buf, "hummingbirds are cool"); |
| sret = func_over_objc_msgForward_pattern (buf); |
| printf ("%s\n", sret); |
| } |
| |
| /* Throw a signal while down on the stack, make sure we can find |
| our way through _sigtramp() and get all the necessary information |
| out of the sigcontext struct to backtrace our way out. */ |
| |
| double func_over_signal_thrower (double d, float f, const char *s) |
| { |
| int c = d * f; |
| c += s[0]; |
| f = f * c; |
| c -= signal_thrower (c); |
| return (d * f) / c; |
| } |
| |
| int signal_thrower (int in) |
| { |
| in--; |
| signal (SIGALRM, handler); |
| alarm (1); |
| sleep (2); |
| in = in - 2; |
| return in; |
| } |
| |
| void handler (int sig) |
| { |
| signal (sig, handler); |
| } |
| |
| |
| |
| /* mov imm32, reg in a prologue. e.g. |
| mov $0xffffffce,%eax |
| reg can be e[abcd]x. Bytes are |
| 0xb[8-b] 4-byte-immediate value. |
| |
| From _ZN18MacFile_DataSource10WriteBytesEtxmPKvPm() aka |
| MacFile_DataSource::WriteBytes(unsigned short, long long, unsigned long, void const*, unsigned long*) |
| in /System/Library/Frameworks/AudioToolbox.framework/Versions/A/AudioToolbox |
| |
| */ |
| |
| int |
| func_over_mov_imm32_addr_in_prologue (int in) |
| { |
| in *= in; |
| in = mov_imm32_reg_in_prologue (in); |
| return in; |
| } |
| |
| asm(".text\n" |
| " .align 8\n" |
| "_mov_imm32_reg_in_prologue:\n" |
| " push %ebp\n" |
| " mov $0xffffffce,%eax\n" |
| " mov %esp,%ebp\n" |
| " sub $0x18,%esp\n" |
| " mov 0x8(%ebp),%eax\n" |
| " addl $0x99,%eax\n" |
| " mov %eax,(%esp)\n" |
| " call _func_under_mov_imm32_reg_in_prologue\n" |
| " mov %eax,0x8(%ebp)\n" |
| " leave\n" |
| " ret\n"); |
| |
| int |
| func_under_mov_imm32_reg_in_prologue (int in) |
| { |
| in /= 2; |
| return in + 5; |
| } |
| |
| |
| |
| /* `cmp imm32,m32' in a prologue, e.g. |
| cmpl $0x0,0xc03a4254 |
| Bytes are |
| 0x83 4-byte-imm 4-byte-addr |
| From Debugger() in xnu. |
| |
| */ |
| |
| double |
| func_over_cmpl_in_prologue (double d, float f) |
| { |
| double c = d * f; |
| c = c * cmpl_in_prologue (); |
| return c; |
| } |
| |
| asm(".text\n" |
| " .align 8\n" |
| "_cmpl_in_prologue:\n" |
| " push %ebp\n" |
| " cmpl $0x0,_main\n" |
| " mov %esp,%ebp\n" |
| " push %ebx\n" |
| " mov $0x5,%eax\n" |
| " push %eax\n" |
| " call _func_under_cmpl_in_prologue\n" |
| " pop %ebx\n" |
| " pop %ebx\n" |
| " pop %ebp\n" |
| " ret\n"); |
| |
| int |
| func_under_cmpl_in_prologue (int in) |
| { |
| in++; |
| in++; |
| return in + 4; |
| } |
| |
| |
| char * |
| func_over_objc_msgForward_pattern (char * in) |
| { |
| int len = strlen (in); |
| char *p; |
| p = &in[objc_msgForward_pattern (3) % len]; |
| return p; |
| } |
| |
| /* objc_msgForward () has some hand-written assembly at the front |
| as a little optimization. So we'll need to recognize that. |
| cmp $0x0,%edx [ 0x83 0xfa 0x00 ] |
| je _objc_msgForward+89 [ 0x74 0x54 ] |
| This function is in /usr/lib/libobjc.dylib. */ |
| |
| asm(".text\n" |
| " .align 8\n" |
| "_objc_msgForward_pattern:\n" |
| " cmp $0x0, %edx\n" |
| " je LM998\n" |
| "LM998:\n" |
| " push %ebp\n" |
| " mov %esp, %ebp\n" |
| " sub $4, %esp\n" |
| " movl $99, (%esp)\n" |
| " call _func_under_objc_msgForward_pattern\n" |
| " add $4, %esp\n" |
| " pop %ebp\n" |
| " ret\n"); |
| |
| int |
| func_under_objc_msgForward_pattern (int in) |
| { |
| in += 10; |
| return in; |
| } |