⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 otccelfn.c

📁 The Obfuscated Tiny C Compiler (OTCC) is a very small C compiler. It generate i386 code,include two
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  Obfuscated Tiny C Compiler with ELF output  Copyright (C) 2001-2003 Fabrice Bellard  This software is provided 'as-is', without any express or implied  warranty.  In no event will the authors be held liable for any damages  arising from the use of this software.  Permission is granted to anyone to use this software for any purpose,  including commercial applications, and to alter it and redistribute it  freely, subject to the following restrictions:  1. The origin of this software must not be misrepresented; you must not     claim that you wrote the original software. If you use this software     in a product, an acknowledgment in the product and its documentation      *is* required.  2. Altered source versions must be plainly marked as such, and must not be     misrepresented as being the original software.  3. This notice may not be removed or altered from any source distribution.*/#ifndef TINY#include <stdarg.h>#endif#include <stdio.h>/* vars: value of variables    loc : local variable index   glo : global variable ptr   data: base of data segment   ind : output code ptr   prog: output code   rsym: return symbol   sym_stk: symbol stack   dstk: symbol stack pointer   dptr, dch: macro state   * 'vars' format:    For each character TAG_TOK at offset 'i' before a    symbol in sym_stk, we have:    v = (int *)(vars + 8 * i + TOK_IDENT)[0]     p = (int *)(vars + 8 * i + TOK_IDENT)[0]         v = 0    : undefined symbol, p = list of use points.    v = 1    : define symbol, p = pointer to define text.    v < LOCAL: offset on stack, p = 0.    otherwise: symbol with value 'v', p = list of use points.   * 'sym_stk' format:   TAG_TOK sym1 TAG_TOK sym2 .... symN '\0'   'dstk' points to the last '\0'.*/int tok, tokc, tokl, ch, vars, rsym, prog, ind, loc, glo, file, sym_stk, dstk, dptr, dch, last_id, data, text, data_offset;#define ALLOC_SIZE 99999#define ELFOUT/* depends on the init string */#define TOK_STR_SIZE 48#define TOK_IDENT    0x100#define TOK_INT      0x100#define TOK_IF       0x120#define TOK_ELSE     0x138#define TOK_WHILE    0x160#define TOK_BREAK    0x190#define TOK_RETURN   0x1c0#define TOK_FOR      0x1f8#define TOK_DEFINE   0x218#define TOK_MAIN     0x250#define TOK_DUMMY   1#define TOK_NUM     2#define LOCAL   0x200#define SYM_FORWARD 0#define SYM_DEFINE  1/* tokens in string heap */#define TAG_TOK    ' '#define TAG_MACRO  2/* additionnal elf output defines */#ifdef ELFOUT#define ELF_BASE      0x08048000#define PHDR_OFFSET   0x30#define INTERP_OFFSET 0x90#define INTERP_SIZE   0x13#ifndef TINY#define DYNAMIC_OFFSET (INTERP_OFFSET + INTERP_SIZE + 1)#define DYNAMIC_SIZE   (11*8)#define ELFSTART_SIZE  (DYNAMIC_OFFSET + DYNAMIC_SIZE)#else#define DYNAMIC_OFFSET 0xa4#define DYNAMIC_SIZE   0x58#define ELFSTART_SIZE  0xfc#endif/* size of startup code */#define STARTUP_SIZE   17/* size of library names at the start of the .dynstr section */#define DYNSTR_BASE      22#endifpdef(t){    *(char *)dstk++ = t;}inp(){    if (dptr) {        ch = *(char *)dptr++;        if (ch == TAG_MACRO) {            dptr = 0;            ch = dch;        }    } else        ch = fgetc(file);    /*    printf("ch=%c 0x%x\n", ch, ch); */}isid(){    return isalnum(ch) | ch == '_';}/* read a character constant */getq(){    if (ch == '\\') {        inp();        if (ch == 'n')            ch = '\n';    }}next(){    int t, l, a;    while (isspace(ch) | ch == '#') {        if (ch == '#') {            inp();            next();            if (tok == TOK_DEFINE) {                next();                pdef(TAG_TOK); /* fill last ident tag */                *(int *)tok = SYM_DEFINE;                *(int *)(tok + 4) = dstk; /* define stack */            }            /* well we always save the values ! */            while (ch != '\n') {                pdef(ch);                inp();            }            pdef(ch);            pdef(TAG_MACRO);        }        inp();    }    tokl = 0;    tok = ch;    /* encode identifiers & numbers */    if (isid()) {        pdef(TAG_TOK);        last_id = dstk;        while (isid()) {            pdef(ch);            inp();        }        if (isdigit(tok)) {            tokc = strtol(last_id, 0, 0);            tok = TOK_NUM;        } else {            *(char *)dstk = TAG_TOK; /* no need to mark end of string (we                                        suppose data is initied to zero */            tok = strstr(sym_stk, last_id - 1) - sym_stk;            *(char *)dstk = 0;   /* mark real end of ident for dlsym() */            tok = tok * 8 + TOK_IDENT;            if (tok > TOK_DEFINE) {                tok = vars + tok;                /*        printf("tok=%s %x\n", last_id, tok); */                /* define handling */                if (*(int *)tok == SYM_DEFINE) {                    dptr = *(int *)(tok + 4);                    dch = ch;                    inp();                    next();                }            }        }    } else {        inp();        if (tok == '\'') {            tok = TOK_NUM;            getq();            tokc = ch;            inp();            inp();        } else if (tok == '/' & ch == '*') {            inp();            while (ch) {                while (ch != '*')                    inp();                inp();                if (ch == '/')                    ch = 0;            }            inp();            next();        } else        {            t = "++#m--%am*@R<^1c/@%[_[H3c%@%[_[H3c+@.B#d-@%:_^BKd<<Z/03e>>`/03e<=0f>=/f<@.f>@1f==&g!=\'g&&k||#l&@.BCh^@.BSi|@.B+j~@/%Yd!@&d*@b";            while (l = *(char *)t++) {                a = *(char *)t++;                tokc = 0;                while ((tokl = *(char *)t++ - 'b') < 0)                    tokc = tokc * 64 + tokl + 64;                if (l == tok & (a == ch | a == '@')) {#if 0                    printf("%c%c -> tokl=%d tokc=0x%x\n",                            l, a, tokl, tokc);#endif                    if (a == ch) {                        inp();                        tok = TOK_DUMMY; /* dummy token for double tokens */                    }                    break;                }            }        }    }#if 0    {        int p;        printf("tok=0x%x ", tok);        if (tok >= TOK_IDENT) {            printf("'");            if (tok > TOK_DEFINE)                 p = sym_stk + 1 + (tok - vars - TOK_IDENT) / 8;            else                p = sym_stk + 1 + (tok - TOK_IDENT) / 8;            while (*(char *)p != TAG_TOK && *(char *)p)                printf("%c", *(char *)p++);            printf("'\n");        } else if (tok == TOK_NUM) {            printf("%d\n", tokc);        } else {            printf("'%c'\n", tok);        }    }#endif}#ifdef TINY#define skip(c) next()#elsevoid error(char *fmt,...){    va_list ap;    va_start(ap, fmt);    fprintf(stderr, "%d: ", ftell((FILE *)file));    vfprintf(stderr, fmt, ap);    fprintf(stderr, "\n");    exit(1);    va_end(ap);}void skip(c){    if (tok != c) {        error("'%c' expected", c);    }    next();}#endif/* from 0 to 4 bytes */o(n){    /* cannot use unsigned, so we must do a hack */    while (n && n != -1) {        *(char *)ind++ = n;        n = n >> 8;    }}#ifdef ELFOUT/* put a 32 bit little endian word 'n' at unaligned address 't' */put32(t, n){    *(char *)t++ = n;    *(char *)t++ = n >> 8;    *(char *)t++ = n >> 16;    *(char *)t++ = n >> 24;}/* get a 32 bit little endian word at unaligned address 't' */get32(t){    int n;    return  (*(char *)t & 0xff) |        (*(char *)(t + 1) & 0xff) << 8 |        (*(char *)(t + 2) & 0xff) << 16 |        (*(char *)(t + 3) & 0xff) << 24;}#else#define put32(t, n) *(int *)t = n#define get32(t) *(int *)t#endif/* output a symbol and patch all references to it */gsym1(t, b){    int n;    while (t) {        n = get32(t); /* next value */        /* patch absolute reference (always mov/lea before) */        if (*(char *)(t - 1) == 0x05) {            /* XXX: incorrect if data < 0 */            if (b >= data && b < glo)                put32(t, b + data_offset);            else                put32(t, b - prog + text + data_offset);        } else {            put32(t, b - t - 4);        }        t = n;    }}gsym(t){    gsym1(t, ind);}/* psym is used to put an instruction with a data field which is a   reference to a symbol. It is in fact the same as oad ! */#define psym oad/* instruction + address */oad(n, t){    o(n);    put32(ind, t);    t = ind;    ind = ind + 4;    return t;}/* load immediate value */li(t){    oad(0xb8, t); /* mov $xx, %eax */}gjmp(t){    return psym(0xe9, t);}/* l = 0: je, l == 1: jne */gtst(l, t){    o(0x0fc085); /* test %eax, %eax, je/jne xxx */    return psym(0x84 + l, t);}gcmp(t){    o(0xc139); /* cmp %eax,%ecx */    li(0);    o(0x0f); /* setxx %al */    o(t + 0x90);    o(0xc0);}gmov(l, t){    int n;    o(l + 0x83);    n = *(int *)t;    if (n && n < LOCAL)        oad(0x85, n);    else {        t = t + 4;        *(int *)t = psym(0x05, *(int *)t);    }}/* l is one if '=' parsing wanted (quick hack) */unary(l){    int n, t, a, c;    n = 1; /* type of expression 0 = forward, 1 = value, other =              lvalue */    if (tok == '\"') {        li(glo + data_offset);        while (ch != '\"') {            getq();            *(char *)glo++ = ch;            inp();        }        *(char *)glo = 0;        glo = glo + 4 & -4; /* align heap */        inp();        next();    } else {        c = tokl;        a = tokc;        t = tok;        next();        if (t == TOK_NUM) {            li(a);        } else if (c == 2) {            /* -, +, !, ~ */            unary(0);            oad(0xb9, 0); /* movl $0, %ecx */            if (t == '!')                gcmp(a);            else                o(a);        } else if (t == '(') {            expr();            skip(')');        } else if (t == '*') {            /* parse cast */            skip('(');            t = tok; /* get type */            next(); /* skip int/char/void */            next(); /* skip '*' or '(' */            if (tok == '*') {                /* function type */                skip('*');                skip(')');                skip('(');                skip(')');                t = 0;            }            skip(')');            unary(0);            if (tok == '=') {                next();                o(0x50); /* push %eax */                expr();                o(0x59); /* pop %ecx */                o(0x0188 + (t == TOK_INT)); /* movl %eax/%al, (%ecx) */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -