constWORLDant

ROOTME Macho keygen or not 본문

0x02 Reverse Engineer/0x03. Etc

ROOTME Macho keygen or not

data type ConS_tanT 2018.05.19 19:05

코드 분석


int __cdecl main(int argc, const char **argv, const char **envp)

{

  __int64 v3; // rsi

  int v4; // eax

  int i; // [rsp+44h] [rbp-6Ch]

  unsigned int key; // [rsp+4Ch] [rbp-64h]

  const char **v8; // [rsp+50h] [rbp-60h]

  int v9; // [rsp+58h] [rbp-58h]

  int v10; // [rsp+5Ch] [rbp-54h]

  char v11; // [rsp+60h] [rbp-50h]

  char shellcode[15]; // [rsp+80h] [rbp-30h]

  char v13; // [rsp+8Fh] [rbp-21h]

  char v14; // [rsp+90h] [rbp-20h]

  char v15; // [rsp+92h] [rbp-1Eh]

  char v16; // [rsp+98h] [rbp-18h]

  __int64 v17; // [rsp+A8h] [rbp-8h]


  v10 = 0;

  v9 = argc;

  v8 = argv;

  memcpy(shellcode, ".what r u trying 2 do?.", 34uLL);

  printf(".username.\n", ".what r u trying 2 do?.");

  fgets(&v11, 32, __stdinp);

  printf(".activation key.\n", 32LL);

  scanf("%u", &key);

  v3 = key;

  if ( (unsigned int)auth((__int64)&v11, key, (__int64)shellcode) )

  {

    printf("NOP\n", v3);

    v10 = -1;

  }

  else

  {

    printf("Authenticated! You can use this password to valid8\n", v3);

    v4 = strnlen(shellcode, 32uLL);

    for ( i = 0; i < v4; ++i )                  // 32

      shellcode[i] = (key ^ shellcode[i]) % 0x7F;// rbp-30h(48bytes)

    v13 = 0x2D;                                 // rbp-21h shellcode[15]

    v14 = 0x64;                                 // rbp-20h shellcode[16]

    v15 = 0x62;                                 // rbp-1eh shellcode[18]

    v16 = 0;

    printf("%s\n", &shellcode[10]);             // 0~10

    v10 = 0;

  }

  if ( __stack_chk_guard != v17 )

    __stack_chk_fail();

  return v10;

}


__int64 __fastcall auth(__int64 a1, int key, __int64 a3)

{

  int v4; // [rsp+14h] [rbp-2Ch]

  signed int len; // [rsp+18h] [rbp-28h]

  signed int i; // [rsp+1Ch] [rbp-24h]

  __int64 v7; // [rsp+20h] [rbp-20h]

  BOOL v8; // [rsp+3Ch] [rbp-4h]


  v7 = a3;

  *(_BYTE *)(a1 + strcspn((const char *)a1, "\n")) = 0;// 널까지 읽어온다

  len = strnlen((const char *)a1, 0x20uLL);

  if ( len >= 6 || len <= 8 )

  {

    if ( ptrace(0, 0, (caddr_t)1, 0) == -1 )

    {

      v8 = 1;

      printf("%s\n", v7);

    }

    else

    {

      v4 = (*(char *)(a1 + 3) ^ 0x1337) + 0x5EEDED;

      for ( i = 0; i < len; ++i )

      {

        if ( *(char *)(a1 + i) < ' ' || *(char *)(a1 + i) > 127 )

          return 1;

        v4 += (v4 ^ (unsigned int)*(char *)(a1 + i)) % 0x539;

      }

      v8 = key != v4 || key != 0x5F2548; // key값 발견 

    }

  }

  else

  {

    v8 = 1;

  }

  return (unsigned int)v8;

}


이런 문제는 auth 함수 복잡한 연산 볼 필요가 없었다. 

왜냐하면 key값만 추출하면 되기 때문이다.


오래 걸렸던 게 memcpy에서 인자 갯수가 맞지 않아 Segmentation Falut가 떴던 것이고, 

그냥 복사하지 않고 data를 그대로 사용하는 것으로 마무리했고, 


printf &data[10]이면 10번째 첨자부터 읽어와야하는데 계속 모든 인덱스를 읽어와서 오래걸렸다. 

재밌다.~ 



소스코드 

#include <stdio.h>

#include <stdlib.h>

#include <Windows.h>

#include <string.h>



int main(void)

{

unsigned int key = 0x5F2548;

char data[] = ".what r u trying 2 do?.";


for (int i = 0; i < strlen((const char*)data); i++)

{

data[i] = (key ^ data[i]) % 0x7F;

}

data[15] = 0x2d;

data[16] = 0x64;

data[18] = 0x62;


for (int i = 10; i < strlen((const char*)data); i++)

{

printf("%c", data[i]);

}


return 0;

}



'0x02 Reverse Engineer > 0x03. Etc' 카테고리의 다른 글

rootme elf-antidebug  (0) 2018.05.22
ROOTME PE-SEHVEH  (0) 2018.05.21
ROOTME Macho keygen or not  (0) 2018.05.19
ROOTME ARM  (0) 2018.05.19
ROOTME NO SOFTWARE BREAKPOINTS  (0) 2018.05.19
ROOTME PYC-BYTECODE  (0) 2018.05.19
0 Comments
댓글쓰기 폼