Reverse(三)

1. open-source

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
    if (argc != 4) {    // argc代表输入数据数目 主要看下面argv[]里的分析
        printf("what?\n");
        exit(1);
    }

    unsigned int first = atoi(argv[1]);
    if (first != 0xcafe) {    // first = 0xcafe(51966)
        printf("you are wrong, sorry.\n");
        exit(2);
    }

    unsigned int second = atoi(argv[2]);
    if (second % 5 == 3 || second % 17 != 8) {    // second模5不能等于3,模17等于8 即second%17=8
        printf("ha, you won't get it!\n");
        exit(3);
    }

    if (strcmp("h4cky0u", argv[3])) {    // 长度为7
        printf("so close, dude!\n");
        exit(4);
    }

    printf("Brr wrrr grr\n");

    unsigned int hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207;

    printf("Get your key: ");
    printf("%x\n", hash);
    return 0;
}

改写下

#include<stdio.h>
int main()
{
    unsigned int hash = 0xcafe * 31337 + 8 * 11 + 7 - 1615810207;
    printf("Get your key: ");
    printf("%x\n", hash);
    return 0;
}

image-20211119202203324.png

得到flag

2. simple-unpack

image-20211119204656547.png

有upx壳

upx脱壳 使用upx -d “文件名”指令

image-20211119205233331.png

拖到ida64找到main函数

image-20211119205341695.png

shift+F12查找字符串flag

image-20211119205520457.png

找到flag

3. logmein

ida64查看伪代码

转换后

#include<stdio.h>
int main()
{
  char v8[]=":\"AL_RT^L*.?+6/46";
  int v6 = 7;
  printf("Welcome to the RC3 secure password guesser.\n");
  printf("To continue, you must enter the correct password.\n");
  printf("Enter your guess: ");
  char s[100];
  scanf("%32s", &s);
  int v3 = strlen(s);
  if ( v3 < strlen(v8) )                        // 输入长度小于18
      printf("incorrect!");                     // 错误
  for (int i = 0; i < strlen(s); ++i )
  {
    if ( i >= strlen(v8) )                      // i大于等于18
      printf("incorrect!"); 
    if ( s[i] != (char)(v8[i % v6 - 8] ^ v8[i]) )// 这里在查询了wp后才知道应该是v7,反编译错误了
        // 别人反编译的是这样的 s[i] != (char)(*((_BYTE *)&v7 + i % v6) ^ v8[i]
      printf("incorrect!"); 
  }
  printf("correct!");                                // 正确
}

主要在这句话上判断

 if ( s[i] != (char)(v7[i % v6] ^ v8[i]) )
      printf("incorrect!"); 

对v7右键转换成char类型,得到v7 = 'ebmarah';

注意需要逆转字符串,原因:x86系列的CPU都是以小端序储存数据的,即低位字节存入低地址,高位字节存入高地址

即 v7 = 'harambe'

#include<stdio.h>
#include<string.h>
#define BYTE unsigned char
int main()
{
    char v7[7] = "harambe";
    char v8[18] = ":\"AL_RT^L*.?+6/46";
    char s[18] = "";
    for (int i = 0; i < strlen(v8); i++)
    {
        s[i] = (char)(*((BYTE *)&v7 + i % 7) ^ v8[i]);
    }
    printf("%s", s);
}

得到 RC3-2016-XORISGUD

小结

UPX一款先进的可执行程序文件压缩器

UPX: the Ultimate Packer for eXecutables - Homepage

最后修改:2023 年 12 月 14 日
如果觉得我的文章对你有用,请随意赞赏