📄 otccelfn.c
字号:
} else if (t) { if (t == TOK_INT) o(0x8b); /* mov (%eax), %eax */ else o(0xbe0f); /* movsbl (%eax), %eax */ ind++; /* add zero in code */ } } else if (t == '&') { gmov(10, tok); /* leal EA, %eax */ next(); } else { n = 0; if (tok == '=' & l) { /* assignment */ next(); expr(); gmov(6, t); /* mov %eax, EA */ } else if (tok != '(') { /* variable */ gmov(8, t); /* mov EA, %eax */ if (tokl == 11) { gmov(0, t); o(tokc); next(); } } } } /* function call */ if (tok == '(') { if (n) o(0x50); /* push %eax */ /* push args and invert order */ a = oad(0xec81, 0); /* sub $xxx, %esp */ next(); l = 0; while(tok != ')') { expr(); oad(0x248489, l); /* movl %eax, xxx(%esp) */ if (tok == ',') next(); l = l + 4; } put32(a, l); next(); if (n) { oad(0x2494ff, l); /* call *xxx(%esp) */ l = l + 4; } else { /* forward reference */ t = t + 4; *(int *)t = psym(0xe8, *(int *)t); } if (l) oad(0xc481, l); /* add $xxx, %esp */ }}sum(l){ int t, n, a; if (l-- == 1) unary(1); else { sum(l); a = 0; while (l == tokl) { n = tok; t = tokc; next(); if (l > 8) { a = gtst(t, a); /* && and || output code generation */ sum(l); } else { o(0x50); /* push %eax */ sum(l); o(0x59); /* pop %ecx */ if (l == 4 | l == 5) { gcmp(t); } else { o(t); if (n == '%') o(0x92); /* xchg %edx, %eax */ } } } /* && and || output code generation */ if (a && l > 8) { a = gtst(t, a); li(t ^ 1); gjmp(5); /* jmp $ + 5 */ gsym(a); li(t); } }}expr(){ sum(11);}test_expr(){ expr(); return gtst(0, 0);}block(l){ int a, n, t; if (tok == TOK_IF) { next(); skip('('); a = test_expr(); skip(')'); block(l); if (tok == TOK_ELSE) { next(); n = gjmp(0); /* jmp */ gsym(a); block(l); gsym(n); /* patch else jmp */ } else { gsym(a); /* patch if test */ } } else if (tok == TOK_WHILE | tok == TOK_FOR) { t = tok; next(); skip('('); if (t == TOK_WHILE) { n = ind; a = test_expr(); } else { if (tok != ';') expr(); skip(';'); n = ind; a = 0; if (tok != ';') a = test_expr(); skip(';'); if (tok != ')') { t = gjmp(0); expr(); gjmp(n - ind - 5); gsym(t); n = t + 4; } } skip(')'); block(&a); gjmp(n - ind - 5); /* jmp */ gsym(a); } else if (tok == '{') { next(); /* declarations */ decl(1); while(tok != '}') block(l); next(); } else { if (tok == TOK_RETURN) { next(); if (tok != ';') expr(); rsym = gjmp(rsym); /* jmp */ } else if (tok == TOK_BREAK) { next(); *(int *)l = gjmp(*(int *)l); } else if (tok != ';') expr(); skip(';'); }}/* 'l' is true if local declarations */decl(l){ int a; while (tok == TOK_INT | tok != -1 & !l) { if (tok == TOK_INT) { next(); while (tok != ';') { if (l) { loc = loc + 4; *(int *)tok = -loc; } else { *(int *)tok = glo; glo = glo + 4; } next(); if (tok == ',') next(); } skip(';'); } else { /* put function address */ *(int *)tok = ind; next(); skip('('); a = 8; while (tok != ')') { /* read param name and compute offset */ *(int *)tok = a; a = a + 4; next(); if (tok == ',') next(); } next(); /* skip ')' */ rsym = loc = 0; o(0xe58955); /* push %ebp, mov %esp, %ebp */ a = oad(0xec81, 0); /* sub $xxx, %esp */ block(0); gsym(rsym); o(0xc3c9); /* leave, ret */ put32(a, loc); /* save local variables */ } }}#ifdef ELFOUTgle32(n){ put32(glo, n); glo = glo + 4;}/* used to generate a program header at offset 't' of size 's' */gphdr1(n, t){ gle32(n); n = n + ELF_BASE; gle32(n); gle32(n); gle32(t); gle32(t);}elf_reloc(l){ int t, a, n, p, b, c; p = 0; t = sym_stk; while (1) { /* extract symbol name */ t++; a = t; while (*(char *)t != TAG_TOK && t < dstk) t++; if (t == dstk) break; /* now see if it is forward defined */ tok = vars + (a - sym_stk) * 8 + TOK_IDENT - 8; b = *(int *)tok; n = *(int *)(tok + 4); if (n && b != 1) {#if 0 { char buf[100]; memcpy(buf, a, t - a); buf[t - a] = '\0'; printf("extern ref='%s' val=%x\n", buf, b); }#endif if (!b) { if (!l) { /* symbol string */ memcpy(glo, a, t - a); glo = glo + t - a + 1; /* add a zero */ } else if (l == 1) { /* symbol table */ gle32(p + DYNSTR_BASE); gle32(0); gle32(0); gle32(0x10); /* STB_GLOBAL, STT_NOTYPE */ p = p + t - a + 1; /* add a zero */ } else { p++; /* generate relocation patches */ while (n) { a = get32(n); /* c = 0: R_386_32, c = 1: R_386_PC32 */ c = *(char *)(n - 1) != 0x05; put32(n, -c * 4); gle32(n - prog + text + data_offset); gle32(p * 256 + c + 1); n = a; } } } else if (!l) { /* generate standard relocation */ gsym1(n, b); } } }}elf_out(c){ int glo_saved, dynstr, dynstr_size, dynsym, hash, rel, n, t, text_size; /*****************************/ /* add text segment (but copy it later to handle relocations) */ text = glo; text_size = ind - prog; /* add the startup code */ ind = prog; o(0x505458); /* pop %eax, push %esp, push %eax */ t = *(int *)(vars + TOK_MAIN); oad(0xe8, t - ind - 5); o(0xc389); /* movl %eax, %ebx */ li(1); /* mov $1, %eax */ o(0x80cd); /* int $0x80 */ glo = glo + text_size; /*****************************/ /* add symbol strings */ dynstr = glo; /* libc name for dynamic table */ glo++; glo = strcpy(glo, "libc.so.6") + 10; glo = strcpy(glo, "libdl.so.2") + 11; /* export all forward referenced functions */ elf_reloc(0); dynstr_size = glo - dynstr; /*****************************/ /* add symbol table */ glo = (glo + 3) & -4; dynsym = glo; gle32(0); gle32(0); gle32(0); gle32(0); elf_reloc(1); /*****************************/ /* add symbol hash table */ hash = glo; n = (glo - dynsym) / 16; gle32(1); /* one bucket (simpler!) */ gle32(n); gle32(1); gle32(0); /* dummy first symbol */ t = 2; while (t < n) gle32(t++); gle32(0); /*****************************/ /* relocation table */ rel = glo; elf_reloc(2); /* copy code AFTER relocation is done */ memcpy(text, prog, text_size); glo_saved = glo; glo = data; /* elf header */ gle32(0x464c457f); gle32(0x00010101); gle32(0); gle32(0); gle32(0x00030002); gle32(1); gle32(text + data_offset); /* address of _start */ gle32(PHDR_OFFSET); /* offset of phdr */ gle32(0); gle32(0); gle32(0x00200034); gle32(3); /* phdr entry count */ /* program headers */ gle32(3); /* PT_INTERP */ gphdr1(INTERP_OFFSET, INTERP_SIZE); gle32(4); /* PF_R */ gle32(1); /* align */ gle32(1); /* PT_LOAD */ gphdr1(0, glo_saved - data); gle32(7); /* PF_R | PF_X | PF_W */ gle32(0x1000); /* align */ gle32(2); /* PT_DYNAMIC */ gphdr1(DYNAMIC_OFFSET, DYNAMIC_SIZE); gle32(6); /* PF_R | PF_W */ gle32(0x4); /* align */ /* now the interpreter name */ glo = strcpy(glo, "/lib/ld-linux.so.2") + 0x14; /* now the dynamic section */ gle32(1); /* DT_NEEDED */ gle32(1); /* libc name */ gle32(1); /* DT_NEEDED */ gle32(11); /* libdl name */ gle32(4); /* DT_HASH */ gle32(hash + data_offset); gle32(6); /* DT_SYMTAB */ gle32(dynsym + data_offset); gle32(5); /* DT_STRTAB */ gle32(dynstr + data_offset); gle32(10); /* DT_STRSZ */ gle32(dynstr_size); gle32(11); /* DT_SYMENT */ gle32(16); gle32(17); /* DT_REL */ gle32(rel + data_offset); gle32(18); /* DT_RELSZ */ gle32(glo_saved - rel); gle32(19); /* DT_RELENT */ gle32(8); gle32(0); /* DT_NULL */ gle32(0); t = fopen(c, "w"); fwrite(data, 1, glo_saved - data, t); fclose(t);}#endifmain(n, t){ if (n < 3) { printf("usage: otccelf file.c outfile\n"); return 0; } dstk = strcpy(sym_stk = calloc(1, ALLOC_SIZE), " int if else while break return for define main ") + TOK_STR_SIZE; glo = data = calloc(1, ALLOC_SIZE); ind = prog = calloc(1, ALLOC_SIZE); vars = calloc(1, ALLOC_SIZE); t = t + 4; file = fopen(*(int *)t, "r"); data_offset = ELF_BASE - data; glo = glo + ELFSTART_SIZE; ind = ind + STARTUP_SIZE; inp(); next(); decl(0); t = t + 4; elf_out(*(int *)t); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -