加密与解密 charter 4 学习记录

0x01 charter 4

4.1.1 start up function

GetStartupInfo --> main --> exit

4.1.2 function

reference

stack  &register  

calling convention

c ďźšright to left

4.1.3  data struct

1.local variables

2.array

.data [407030h + eax ]

base + offset

4.1.4 virtual function

virtual table

4.1.5 control statement

cmp  
test  or

long jump

short jump

call

4.1.6 cool

xor ecx, ecx ;ecx to zero
inc ecx   ; ecx + 1
cmp ecx,05
jbe 0044000  

4.1.7 math operator

add sub

c = a + b +78h
lea c,[a+b+78]

mul imul shl

eax*5
lea eax,[eax+4*eax]

div idiv shr a,n

cdq --> let eax to sign ,the first to edx
a / b = a ∗ 1 / b a/b = a * 1/b a/b=a∗1/b
4.1.8 strings

lea eax,[eax + 8]  add eax ,8
A-Z 41-5A
a-z 61-7A

strlen()

4.1.9 statement change technology

4.2 x64

calling convention

right to left

front 4 reference by register

rcx rdx r8 r9

0x02 charter 5 show protect technology

5.1 keygen

5.1.1 ĺ

find F’’ --> F

(3) F1(user) = F2(keygen)

5.1.2 how to attack keygen

  1. the scret of data constraint

    +ORC

    we use Olly to find the keygen,run–>input prediy and keygen, F7 --> memery window --> Ctrl + B find keygen

    
    

    we find the keygen 4549

5.1.5 string compare style

1.register compare directly

mov eax []
mov ebx []
cmp eax,ebx
jz (jnz) xxx

2.function compare

mov eax []
mov ebx []
call xxxxxxx
test eax eax
jz (jnz)
push xxxx
push xxxx
call xxxxxx
test eax eax 
jz (jnz)

3.string compare

lea edi []
lea esi []
repz cmpsd
jz jnz

5.1.4 create Register machine

the main code is here

00401228                 push    offset String
CODE:0040122D                 call    sub_40137E
CODE:00401232                 push    eax
CODE:00401233                 push    offset byte_40217E
CODE:00401238                 call    sub_4013D8
CODE:0040123D                 add     esp, 4
CODE:00401240                 pop     eax
CODE:00401241                 cmp     eax, ebx
CODE:00401243                 jz      short loc_40124C
CODE:00401245                 call    sub_401362
CODE:0040124A                 jmp     short loc_4011E6
int __usercall sub_40137E@<eax>(int a1@<ebp>, int a2@<edi>, unsigned __int8 *a3)
{
  unsigned __int8 *i; // esi
  unsigned __int8 v4; // al

  for ( i = a3; ; ++i )
  {
    v4 = *i;
    if ( !*i )
    {
      sub_4013C2();
      return a2 ^ 0x5678;
    }
    if ( v4 < 0x41u )
      break;
    if ( v4 >= 0x5Au )
      sub_4013D2();// 
  }
  return MessageBoxA(*(HWND *)(a1 + 8), aIncorrectTryAg, aError, 0x30u);
}
int F1(char *name)
{
int i,k=0;
 char v4;
  for ( i =0; name[i]!=0; i++ )
  {
    v4 = name[i];
    if ( v4 < 0x41u )
      break;
    if ( v4 >= 0x5Au )  // k += (v4>'Z'?(v4-32):v4);
      k+ = v4-32;
      else k+ = v4;
  }
    k=k ^ 0x5678
  return k;
}
char __cdecl sub_4013D8(_BYTE *a1)
{
  int v1; // eax
  int v2; // edi  /edi
  int v3; // ebx
  _BYTE *i; // esi

  v1 = 0;
  v2 = 0;
  v3 = 0;
  for ( i = a1; ; ++i )
  {
    LOBYTE(v1) = 10;
    if ( !*i )
      break;
    LOBYTE(v3) = *i - 48;
    v2 = v3 + v1 * v2;
  }
  return v1;
}

int F2(char *code)
{
    int i,v2=0;
    for(i=0;code[i]!=0;i++)
    {
        v2+ = code[i]-0x30 + 0xA * v2;
    }
    v2 = v2^0x1234;
    return v2;
    }
123 --> 0*10+1 --> 1*10+2-->12*10+3 =123
    v2 = 123 ^ 0x1234
    if code = 123 ^ 0x1234 
        then we can find the keygen

if k1==v2 we can get the keygen.how can we do this ?

we must find the reverse of F2 ,we use F1 find the k1

nt keygen(char *name)
{
int i,k=0;
 char v4;
  for ( i =0; name[i]!=0; i++ )
  {
    v4 = name[i];
    if ( v4 < 0x41u )
      break;
    if ( v4 >= 0x5Au )  // k += (v4>'Z'?(v4-32):v4);
      k+ = v4-32;
      else k+ = v4;
  }
    k=k ^ 0x5678
  return k^0x1234;
}

k^0x1234 --> code --> v2 = k^0x1234^0x1234

make a awd pwn

c4

https://github.com/rswier/c4/blob/master/c4.c we change c4 project as our vul pwn

// c4.c - C in four functions
// char, int, and pointer types
// if, while, return, and expression statements
// just enough features to allow self-compilation and a bit more
// Written by Robert Swierczek


#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <unistd.h>
#include <fcntl.h>
#define int long long


char *p, *lp, // current position in source code
     *data;   // data/bss pointer
int *e, *le,  // current position in emitted code
    *id,      // currently parsed identifier
    *sym,     // symbol table (simple list of identifiers)
    tk,       // current token
    ival,     // current token value
    ty,       // current expression type
    loc,      // local variable offset
    line,     // current line number
    src,      // print source and assembly flag
    debug;    // print executed instructions


// tokens and classes (operators last and in precedence order)
enum {
  Num = 128, Fun, Sys, Glo, Loc, Id,
  Char, Else, Enum, If, Int, Return, Sizeof, While,
  Assign, Cond, Lor, Lan, Or, Xor, And, Eq, Ne, Lt, Gt, Le, Ge, Shl, Shr, Add, Sub, Mul, Div, Mod, Inc, Dec, Brak
};



// opcodes

enum { LEA ,IMM ,JMP ,JSR ,BZ  ,BNZ ,ENT ,ADJ ,LEV ,LI  ,LC  ,SI  ,SC  ,PSH ,
       OR  ,XOR ,AND ,EQ  ,NE  ,LT  ,GT  ,LE  ,GE  ,SHL ,SHR ,ADD ,SUB ,MUL ,DIV ,MOD ,
       OPEN,READ,CLOS,PRTF,MALC,FREE,MSET,MCMP,EXIT };



// types
enum { CHAR, INT, PTR };

// identifier offsets (since we can't create an ident struct)
enum { Tk, Hash, Name, Class, Type, Val, HClass, HType, HVal, Idsz };



void next()
{
  char *pp;
  while (tk = *p) {
    ++p;
    if (tk == '\n') {
      if (src) {
        printf("%d: %.*s", line, p - lp, lp);
        lp = p;
        while (le < e) {
          printf("%8.4s", &"LEA ,IMM ,JMP ,JSR ,BZ  ,BNZ ,ENT ,ADJ ,LEV ,LI  ,LC  ,SI  ,SC  ,PSH ,"
                           "OR  ,XOR ,AND ,EQ  ,NE  ,LT  ,GT  ,LE  ,GE  ,SHL ,SHR ,ADD ,SUB ,MUL ,DIV ,MOD ,"
                           "OPEN,READ,CLOS,PRTF,MALC,FREE,MSET,MCMP,EXIT,"[*++le * 5]);
          if (*le <= ADJ) printf(" %d\n", *++le); else printf("\n");
        }
      }
      ++line;
    }
    else if (tk == '#') {
      while (*p != 0 && *p != '\n') ++p;
    }
    else if ((tk >= 'a' && tk <= 'z') || (tk >= 'A' && tk <= 'Z') || tk == '_') {
      pp = p - 1;
      while ((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z') || (*p >= '0' && *p <= '9') || *p == '_')
        tk = tk * 147 + *p++;
      tk = (tk << 6) + (p - pp);
      id = sym;
      while (id[Tk]) {
        if (tk == id[Hash] && !memcmp((char *)id[Name], pp, p - pp)) { tk = id[Tk]; return; }
        id = id + Idsz;
      }
      id[Name] = (int)pp;
      id[Hash] = tk;
      tk = id[Tk] = Id;
      return;
    }

    else if (tk >= '0' && tk <= '9') {
      if (ival = tk - '0') { while (*p >= '0' && *p <= '9') ival = ival * 10 + *p++ - '0'; }
      else if (*p == 'x' || *p == 'X') {
        while ((tk = *++p) && ((tk >= '0' && tk <= '9') || (tk >= 'a' && tk <= 'f') || (tk >= 'A' && tk <= 'F')))
          ival = ival * 16 + (tk & 15) + (tk >= 'A' ? 9 : 0);
      }

      else { while (*p >= '0' && *p <= '7') ival = ival * 8 + *p++ - '0'; }
      tk = Num;
      return;

    }
    else if (tk == '/') {
      if (*p == '/') {
        ++p;
        while (*p != 0 && *p != '\n') ++p;
      }

      else {
        tk = Div;
        return;
      }

    }

    else if (tk == '\'' || tk == '"') {
      pp = data;
      while (*p != 0 && *p != tk) {
        if ((ival = *p++) == '\\') {
          if ((ival = *p++) == 'n') ival = '\n';
        }
        if (tk == '"') *data++ = ival;
      }
      ++p;
      if (tk == '"') ival = (int)pp; else tk = Num;
      return;
    }

    else if (tk == '=') { if (*p == '=') { ++p; tk = Eq; } else tk = Assign; return; }
    else if (tk == '+') { if (*p == '+') { ++p; tk = Inc; } else tk = Add; return; }
    else if (tk == '-') { if (*p == '-') { ++p; tk = Dec; } else tk = Sub; return; }
    else if (tk == '!') { if (*p == '=') { ++p; tk = Ne; } return; }
    else if (tk == '<') { if (*p == '=') { ++p; tk = Le; } else if (*p == '<') { ++p; tk = Shl; } else tk = Lt; return; }
    else if (tk == '>') { if (*p == '=') { ++p; tk = Ge; } else if (*p == '>') { ++p; tk = Shr; } else tk = Gt; return; }
    else if (tk == '|') { if (*p == '|') { ++p; tk = Lor; } else tk = Or; return; }
    else if (tk == '&') { if (*p == '&') { ++p; tk = Lan; } else tk = And; return; }
    else if (tk == '^') { tk = Xor; return; }
    else if (tk == '%') { tk = Mod; return; }
    else if (tk == '*') { tk = Mul; return; }
    else if (tk == '[') { tk = Brak; return; }
    else if (tk == '?') { tk = Cond; return; }
    else if (tk == '~' || tk == ';' || tk == '{' || tk == '}' || tk == '(' || tk == ')' || tk == ']' || tk == ',' || tk == ':') return;

  }

}



void expr(int lev)

{

  int t, *d;
  if (!tk) { printf("%d: unexpected eof in expression\n", line); exit(-1); }
  else if (tk == Num) { *++e = IMM; *++e = ival; next(); ty = INT; }

  else if (tk == '"') {

    *++e = IMM; *++e = ival; next();

    while (tk == '"') next();

    data = (char *)((int)data + sizeof(int) & -sizeof(int)); ty = PTR;

  }

  else if (tk == Sizeof) {

    next(); if (tk == '(') next(); else { printf("%d: open paren expected in sizeof\n", line); exit(-1); }

    ty = INT; if (tk == Int) next(); else if (tk == Char) { next(); ty = CHAR; }

    while (tk == Mul) { next(); ty = ty + PTR; }

    if (tk == ')') next(); else { printf("%d: close paren expected in sizeof\n", line); exit(-1); }

    *++e = IMM; *++e = (ty == CHAR) ? sizeof(char) : sizeof(int);

    ty = INT;

  }

  else if (tk == Id) {

    d = id; next();

    if (tk == '(') {

      next();

      t = 0;

      while (tk != ')') { expr(Assign); *++e = PSH; ++t; if (tk == ',') next(); }

      next();

      if (d[Class] == Sys) *++e = d[Val];

      else if (d[Class] == Fun) { *++e = JSR; *++e = d[Val]; }

      else { printf("%d: bad function call\n", line); exit(-1); }

      if (t) { *++e = ADJ; *++e = t; }

      ty = d[Type];

    }

    else if (d[Class] == Num) { *++e = IMM; *++e = d[Val]; ty = INT; }

    else {

      if (d[Class] == Loc) { *++e = LEA; *++e = loc - d[Val]; }

      else if (d[Class] == Glo) { *++e = IMM; *++e = d[Val]; }

      else { printf("%d: undefined variable\n", line); exit(-1); }

      *++e = ((ty = d[Type]) == CHAR) ? LC : LI;

    }

  }

  else if (tk == '(') {

    next();

    if (tk == Int || tk == Char) {

      t = (tk == Int) ? INT : CHAR; next();

      while (tk == Mul) { next(); t = t + PTR; }

      if (tk == ')') next(); else { printf("%d: bad cast\n", line); exit(-1); }

      expr(Inc);

      ty = t;

    }

    else {

      expr(Assign);

      if (tk == ')') next(); else { printf("%d: close paren expected\n", line); exit(-1); }

    }

  }

  else if (tk == Mul) {

    next(); expr(Inc);

    if (ty > INT) ty = ty - PTR; else { printf("%d: bad dereference\n", line); exit(-1); }

    *++e = (ty == CHAR) ? LC : LI;

  }

  else if (tk == And) {

    next(); expr(Inc);

    if (*e == LC || *e == LI) --e; else { printf("%d: bad address-of\n", line); exit(-1); }

    ty = ty + PTR;

  }

  else if (tk == '!') { next(); expr(Inc); *++e = PSH; *++e = IMM; *++e = 0; *++e = EQ; ty = INT; }

  else if (tk == '~') { next(); expr(Inc); *++e = PSH; *++e = IMM; *++e = -1; *++e = XOR; ty = INT; }

  else if (tk == Add) { next(); expr(Inc); ty = INT; }

  else if (tk == Sub) {

    next(); *++e = IMM;

    if (tk == Num) { *++e = -ival; next(); } else { *++e = -1; *++e = PSH; expr(Inc); *++e = MUL; }

    ty = INT;

  }

  else if (tk == Inc || tk == Dec) {

    t = tk; next(); expr(Inc);

    if (*e == LC) { *e = PSH; *++e = LC; }

    else if (*e == LI) { *e = PSH; *++e = LI; }

    else { printf("%d: bad lvalue in pre-increment\n", line); exit(-1); }

    *++e = PSH;

    *++e = IMM; *++e = (ty > PTR) ? sizeof(int) : sizeof(char);

    *++e = (t == Inc) ? ADD : SUB;

    *++e = (ty == CHAR) ? SC : SI;

  }

  else { printf("%d: bad expression\n", line); exit(-1); }



  while (tk >= lev) { // "precedence climbing" or "Top Down Operator Precedence" method

    t = ty;

    if (tk == Assign) {

      next();

      if (*e == LC || *e == LI) *e = PSH; else { printf("%d: bad lvalue in assignment\n", line); exit(-1); }

      expr(Assign); *++e = ((ty = t) == CHAR) ? SC : SI;

    }

    else if (tk == Cond) {

      next();

      *++e = BZ; d = ++e;

      expr(Assign);

      if (tk == ':') next(); else { printf("%d: conditional missing colon\n", line); exit(-1); }

      *d = (int)(e + 3); *++e = JMP; d = ++e;

      expr(Cond);

      *d = (int)(e + 1);

    }

    else if (tk == Lor) { next(); *++e = BNZ; d = ++e; expr(Lan); *d = (int)(e + 1); ty = INT; }

    else if (tk == Lan) { next(); *++e = BZ;  d = ++e; expr(Or);  *d = (int)(e + 1); ty = INT; }

    else if (tk == Or)  { next(); *++e = PSH; expr(Xor); *++e = OR;  ty = INT; }

    else if (tk == Xor) { next(); *++e = PSH; expr(And); *++e = XOR; ty = INT; }

    else if (tk == And) { next(); *++e = PSH; expr(Eq);  *++e = AND; ty = INT; }

    else if (tk == Eq)  { next(); *++e = PSH; expr(Lt);  *++e = EQ;  ty = INT; }

    else if (tk == Ne)  { next(); *++e = PSH; expr(Lt);  *++e = NE;  ty = INT; }

    else if (tk == Lt)  { next(); *++e = PSH; expr(Shl); *++e = LT;  ty = INT; }

    else if (tk == Gt)  { next(); *++e = PSH; expr(Shl); *++e = GT;  ty = INT; }

    else if (tk == Le)  { next(); *++e = PSH; expr(Shl); *++e = LE;  ty = INT; }

    else if (tk == Ge)  { next(); *++e = PSH; expr(Shl); *++e = GE;  ty = INT; }

    else if (tk == Shl) { next(); *++e = PSH; expr(Add); *++e = SHL; ty = INT; }

    else if (tk == Shr) { next(); *++e = PSH; expr(Add); *++e = SHR; ty = INT; }

    else if (tk == Add) {

      next(); *++e = PSH; expr(Mul);

      if ((ty = t) > PTR) { *++e = PSH; *++e = IMM; *++e = sizeof(int); *++e = MUL;  }

      *++e = ADD;

    }

    else if (tk == Sub) {

      next(); *++e = PSH; expr(Mul);

      if (t > PTR && t == ty) { *++e = SUB; *++e = PSH; *++e = IMM; *++e = sizeof(int); *++e = DIV; ty = INT; }

      else if ((ty = t) > PTR) { *++e = PSH; *++e = IMM; *++e = sizeof(int); *++e = MUL; *++e = SUB; }

      else *++e = SUB;

    }

    else if (tk == Mul) { next(); *++e = PSH; expr(Inc); *++e = MUL; ty = INT; }

    else if (tk == Div) { next(); *++e = PSH; expr(Inc); *++e = DIV; ty = INT; }

    else if (tk == Mod) { next(); *++e = PSH; expr(Inc); *++e = MOD; ty = INT; }

    else if (tk == Inc || tk == Dec) {

      if (*e == LC) { *e = PSH; *++e = LC; }

      else if (*e == LI) { *e = PSH; *++e = LI; }

      else { printf("%d: bad lvalue in post-increment\n", line); exit(-1); }

      *++e = PSH; *++e = IMM; *++e = (ty > PTR) ? sizeof(int) : sizeof(char);

      *++e = (tk == Inc) ? ADD : SUB;

      *++e = (ty == CHAR) ? SC : SI;

      *++e = PSH; *++e = IMM; *++e = (ty > PTR) ? sizeof(int) : sizeof(char);

      *++e = (tk == Inc) ? SUB : ADD;

      next();

    }

    else if (tk == Brak) {

      next(); *++e = PSH; expr(Assign);

      if (tk == ']') next(); else { printf("%d: close bracket expected\n", line); exit(-1); }

      if (t > PTR) { *++e = PSH; *++e = IMM; *++e = sizeof(int); *++e = MUL;  }

      else if (t < PTR) { printf("%d: pointer type expected\n", line); exit(-1); }

      *++e = ADD;

      *++e = ((ty = t - PTR) == CHAR) ? LC : LI;

    }

    else { printf("%d: compiler error tk=%d\n", line, tk); exit(-1); }

  }

}



void stmt()

{

  int *a, *b;



  if (tk == If) {

    next();

    if (tk == '(') next(); else { printf("%d: open paren expected\n", line); exit(-1); }

    expr(Assign);

    if (tk == ')') next(); else { printf("%d: close paren expected\n", line); exit(-1); }

    *++e = BZ; b = ++e;

    stmt();

    if (tk == Else) {

      *b = (int)(e + 3); *++e = JMP; b = ++e;

      next();

      stmt();

    }

    *b = (int)(e + 1);

  }

  else if (tk == While) {

    next();

    a = e + 1;

    if (tk == '(') next(); else { printf("%d: open paren expected\n", line); exit(-1); }

    expr(Assign);

    if (tk == ')') next(); else { printf("%d: close paren expected\n", line); exit(-1); }

    *++e = BZ; b = ++e;

    stmt();

    *++e = JMP; *++e = (int)a;

    *b = (int)(e + 1);

  }

  else if (tk == Return) {

    next();

    if (tk != ';') expr(Assign);

    *++e = LEV;

    if (tk == ';') next(); else { printf("%d: semicolon expected\n", line); exit(-1); }

  }

  else if (tk == '{') {

    next();

    while (tk != '}') stmt();

    next();

  }

  else if (tk == ';') {

    next();

  }

  else {

    expr(Assign);

    if (tk == ';') next(); else { printf("%d: semicolon expected\n", line); exit(-1); }

  }

}



int main(int argc, char **argv)

{

  int fd, bt, ty, poolsz, *idmain;

  int *pc, *sp, *bp, a, cycle; // vm registers

  int i, *t; // temps



  --argc; ++argv;

  if (argc > 0 && **argv == '-' && (*argv)[1] == 's') { src = 1; --argc; ++argv; }

  if (argc > 0 && **argv == '-' && (*argv)[1] == 'd') { debug = 1; --argc; ++argv; }

  if (argc < 1) { printf("usage: c4 [-s] [-d] file ...\n"); return -1; }



  if ((fd = open(*argv, 0)) < 0) { printf("could not open(%s)\n", *argv); return -1; }



  poolsz = 256*1024; // arbitrary size

  if (!(sym = malloc(poolsz))) { printf("could not malloc(%d) symbol area\n", poolsz); return -1; }

  if (!(le = e = malloc(poolsz))) { printf("could not malloc(%d) text area\n", poolsz); return -1; }

  if (!(data = malloc(poolsz))) { printf("could not malloc(%d) data area\n", poolsz); return -1; }

  if (!(sp = malloc(poolsz))) { printf("could not malloc(%d) stack area\n", poolsz); return -1; }



  memset(sym,  0, poolsz);

  memset(e,    0, poolsz);

  memset(data, 0, poolsz);



  p = "char else enum if int return sizeof while "

      "open read close printf malloc free memset memcmp exit void main";

  i = Char; while (i <= While) { next(); id[Tk] = i++; } // add keywords to symbol table

  i = OPEN; while (i <= EXIT) { next(); id[Class] = Sys; id[Type] = INT; id[Val] = i++; } // add library to symbol table

  next(); id[Tk] = Char; // handle void type

  next(); idmain = id; // keep track of main



  if (!(lp = p = malloc(poolsz))) { printf("could not malloc(%d) source area\n", poolsz); return -1; }

  if ((i = read(fd, p, poolsz-1)) <= 0) { printf("read() returned %d\n", i); return -1; }

  p[i] = 0;

  close(fd);



  // parse declarations

  line = 1;

  next();

  while (tk) {

    bt = INT; // basetype

    if (tk == Int) next();

    else if (tk == Char) { next(); bt = CHAR; }

    else if (tk == Enum) {

      next();

      if (tk != '{') next();

      if (tk == '{') {

        next();

        i = 0;

        while (tk != '}') {

          if (tk != Id) { printf("%d: bad enum identifier %d\n", line, tk); return -1; }

          next();

          if (tk == Assign) {

            next();

            if (tk != Num) { printf("%d: bad enum initializer\n", line); return -1; }

            i = ival;

            next();

          }

          id[Class] = Num; id[Type] = INT; id[Val] = i++;

          if (tk == ',') next();

        }

        next();

      }

    }

    while (tk != ';' && tk != '}') {

      ty = bt;

      while (tk == Mul) { next(); ty = ty + PTR; }

      if (tk != Id) { printf("%d: bad global declaration\n", line); return -1; }

      if (id[Class]) { printf("%d: duplicate global definition\n", line); return -1; }

      next();

      id[Type] = ty;

      if (tk == '(') { // function

        id[Class] = Fun;

        id[Val] = (int)(e + 1);

        next(); i = 0;

        while (tk != ')') {

          ty = INT;

          if (tk == Int) next();

          else if (tk == Char) { next(); ty = CHAR; }

          while (tk == Mul) { next(); ty = ty + PTR; }

          if (tk != Id) { printf("%d: bad parameter declaration\n", line); return -1; }

          if (id[Class] == Loc) { printf("%d: duplicate parameter definition\n", line); return -1; }

          id[HClass] = id[Class]; id[Class] = Loc;

          id[HType]  = id[Type];  id[Type] = ty;

          id[HVal]   = id[Val];   id[Val] = i++;

          next();

          if (tk == ',') next();

        }

        next();

        if (tk != '{') { printf("%d: bad function definition\n", line); return -1; }

        loc = ++i;

        next();

        while (tk == Int || tk == Char) {

          bt = (tk == Int) ? INT : CHAR;

          next();

          while (tk != ';') {

            ty = bt;

            while (tk == Mul) { next(); ty = ty + PTR; }

            if (tk != Id) { printf("%d: bad local declaration\n", line); return -1; }

            if (id[Class] == Loc) { printf("%d: duplicate local definition\n", line); return -1; }

            id[HClass] = id[Class]; id[Class] = Loc;

            id[HType]  = id[Type];  id[Type] = ty;

            id[HVal]   = id[Val];   id[Val] = ++i;

            next();

            if (tk == ',') next();

          }

          next();

        }

        *++e = ENT; *++e = i - loc;

        while (tk != '}') stmt();

        *++e = LEV;

        id = sym; // unwind symbol table locals

        while (id[Tk]) {

          if (id[Class] == Loc) {

            id[Class] = id[HClass];

            id[Type] = id[HType];

            id[Val] = id[HVal];

          }

          id = id + Idsz;

        }

      }

      else {

        id[Class] = Glo;

        id[Val] = (int)data;

        data = data + sizeof(int);

      }

      if (tk == ',') next();

    }

    next();

  }



  if (!(pc = (int *)idmain[Val])) { printf("main() not defined\n"); return -1; }

  if (src) return 0;



  // setup stack

  bp = sp = (int *)((int)sp + poolsz);

  *--sp = EXIT; // call exit if main returns

  *--sp = PSH; t = sp;

  *--sp = argc;

  *--sp = (int)argv;

  *--sp = (int)t;



  // run...

  cycle = 0;

  while (1) {

    i = *pc++; ++cycle;

    if (debug) {

      printf("%d> %.4s", cycle,

        &"LEA ,IMM ,JMP ,JSR ,BZ  ,BNZ ,ENT ,ADJ ,LEV ,LI  ,LC  ,SI  ,SC  ,PSH ,"

         "OR  ,XOR ,AND ,EQ  ,NE  ,LT  ,GT  ,LE  ,GE  ,SHL ,SHR ,ADD ,SUB ,MUL ,DIV ,MOD ,"

         "OPEN,READ,CLOS,PRTF,MALC,FREE,MSET,MCMP,EXIT,"[i * 5]);

      if (i <= ADJ) printf(" %d\n", *pc); else printf("\n");

    }

    if      (i == LEA) a = (int)(bp + *pc++);                             // load local address

    else if (i == IMM) a = *pc++;                                         // load global address or immediate

    else if (i == JMP) pc = (int *)*pc;                                   // jump

    else if (i == JSR) { *--sp = (int)(pc + 1); pc = (int *)*pc; }        // jump to subroutine

    else if (i == BZ)  pc = a ? pc + 1 : (int *)*pc;                      // branch if zero

    else if (i == BNZ) pc = a ? (int *)*pc : pc + 1;                      // branch if not zero

    else if (i == ENT) { *--sp = (int)bp; bp = sp; sp = sp - *pc++; }     // enter subroutine

    else if (i == ADJ) sp = sp + *pc++;                                   // stack adjust

    else if (i == LEV) { sp = bp; bp = (int *)*sp++; pc = (int *)*sp++; } // leave subroutine

    else if (i == LI)  a = *(int *)a;                                     // load int

    else if (i == LC)  a = *(char *)a;                                    // load char

    else if (i == SI)  *(int *)*sp++ = a;                                 // store int

    else if (i == SC)  a = *(char *)*sp++ = a;                            // store char

    else if (i == PSH) *--sp = a;                                         // push



    else if (i == OR)  a = *sp++ |  a;

    else if (i == XOR) a = *sp++ ^  a;

    else if (i == AND) a = *sp++ &  a;

    else if (i == EQ)  a = *sp++ == a;

    else if (i == NE)  a = *sp++ != a;

    else if (i == LT)  a = *sp++ <  a;

    else if (i == GT)  a = *sp++ >  a;

    else if (i == LE)  a = *sp++ <= a;

    else if (i == GE)  a = *sp++ >= a;

    else if (i == SHL) a = *sp++ << a;

    else if (i == SHR) a = *sp++ >> a;

    else if (i == ADD) a = *sp++ +  a;

    else if (i == SUB) a = *sp++ -  a;

    else if (i == MUL) a = *sp++ *  a;

    else if (i == DIV) a = *sp++ /  a;

    else if (i == MOD) a = *sp++ %  a;



    else if (i == OPEN) a = open((char *)sp[1], *sp);

    else if (i == READ) a = read(sp[2], (char *)sp[1], *sp);

    else if (i == CLOS) a = close(*sp);

    else if (i == PRTF) { t = sp + pc[1]; a = printf((char *)t[-1], t[-2], t[-3], t[-4], t[-5], t[-6]); }

    else if (i == MALC) a = (int)malloc(*sp);

    else if (i == FREE) free((void *)*sp);

    else if (i == MSET) a = (int)memset((char *)sp[2], sp[1], *sp);

    else if (i == MCMP) a = memcmp((char *)sp[2], (char *)sp[1], *sp);

    else if (i == EXIT) { printf("exit(%d) cycle = %d\n", *sp, cycle); return *sp; }

    else { printf("unknown instruction = %d! cycle = %d\n", i, cycle); return -1; }

  }

}

task1 sysmagic

ldd xxx

to check ddl

directly nop if then print the flag:

CTF{debugger_1s_so_p0werful_1n_dyn4m1c_4n4lySis!}
上一篇:洛谷 P1443 马的遍历


下一篇:从格点最短路模型谈起