[网鼎杯 2020 青龙组]jocker

[网鼎杯 2020 青龙组]jocker

SMC(self-Modifying Code): 自修改代码,程序在执行某段代码的过程中会对程序的代码进行修改,只有在修改后的代码才是可汇编,可执行的。在程序未对该段代码进行修改之前,在静态分析状态下,均是不可读的字节码。

查壳:32位无壳程序,直接拖ida

首先shift+f12搜索字符串,但是除了main函数中的一句请输入flag提示之外在没有什么有用的。

main函数

// positive sp value has been detected, the output may be wrong!
int __cdecl main(int argc, const char **argv, const char **envp)
{
  char Str[50]; // [esp+12h] [ebp-96h] BYREF
  char Destination[80]; // [esp+44h] [ebp-64h] BYREF
  DWORD flOldProtect; // [esp+94h] [ebp-14h] BYREF
  size_t v7; // [esp+98h] [ebp-10h]
  int i; // [esp+9Ch] [ebp-Ch]
​
  __main();
  puts("please input you flag:");
  if ( !VirtualProtect(encrypt, 0xC8u, 4u, &flOldProtect) )
    exit(1);
  scanf("%40s", Str);
  v7 = strlen(Str);
  if ( v7 != 24 )
  {
    puts("Wrong!");
    exit(0);
  }
  strcpy(Destination, Str);
  wrong(Str);
  omg(Str);
  for ( i = 0; i <= 186; ++i )
    *((_BYTE *)encrypt + i) ^= 0x41u;
  if ( encrypt(Destination) )
    finally(Destination);
  return 0;
}

可以看到第一个条件是flag长度要为24

然后将str先复制到Destination这里,再调用wrong函数对str进行修改。

wrong函数

char *__cdecl wrong(char *a1)
{
  char *result; // eax
  int i; // [esp+Ch] [ebp-4h]
​
  for ( i = 0; i <= 23; ++i )
  {
    result = &a1[i];
    if ( (i & 1) != 0 )
      a1[i] -= i;       //i为偶数
    else
      a1[i] ^= i;       //i为奇数
  }
  return result;
}

可以看出wrong函数的功能是把a1里每个元素按照下标的奇偶进行相应的加密处理

然后来到omg函数

omg函数

int __cdecl omg(char *a1)
{
  int v2[24]; // [esp+18h] [ebp-80h] BYREF
  int i; // [esp+78h] [ebp-20h]
  int v4; // [esp+7Ch] [ebp-1Ch]
​
  v4 = 1;
  qmemcpy(v2, &unk_4030C0, sizeof(v2));
  for ( i = 0; i <= 23; ++i )
  {
    if ( a1[i] != v2[i] )
      v4 = 0;
  }
  if ( v4 == 1 )
    return puts("hahahaha_do_you_find_me?");
  else
    return puts("wrong ~~ But seems a little program");
}

查看unk_430C0部分

 

直接给出字符串了,破解一下吧(shift + E直接导出字符串)

key = 0x66, 0x6B, 0x63, 0x64, 0x7F, 0x61, 0x67, 0x64, 0x3B, 0x56, 0x6B, 0x61, 0x7B, 0x26, 0x3B, 0x50, 0x63,       0x5F, 0x4D, 0x5A, 0x71, 0x0C, 0x37, 0x66
flag = ''
for i in range(24):
    if i % 2 == 1:
        flag += chr(key[i] + i)
    else:
        flag += chr(key[i] ^ i)
print(flag)
#结果: 
#flag{fak3_alw35_sp_me!!}

假的flag

在omg后面还有一个循环,最后的一点应该是在这里的

循环中还有一个encrypt函数,但是无法打开

红色标注的下面那里像是一段乱码一样,导致无法反汇编出来结果吧,然后尝试找出调用了encrypt函数的地址,od动调一下,看看这个函数到底在干什么

在这里发现了encrypt函数和finally函数分别被调用

既然由前面的函数得到的flag是个假的,那最后正确的flag一定是通过这两个函数处理的,下一步就是分析encrypt函数

OD打开后 在0x401833地址处下断点

 

然后F9运行至断点处,在应用中随意输入24位字符

然后F7步入

 

可以看到这里的函数是已经解密了,然后可以直接olldump脱壳,直接保存新的exe

然后再用ida打开它

encrypt函数

int __cdecl start(int a1)
{
  int v2[19]; // [esp+1Ch] [ebp-6Ch] BYREF
  int v3; // [esp+68h] [ebp-20h]
  int i; // [esp+6Ch] [ebp-1Ch]
​
  v3 = 1;
  qmemcpy(v2, &unk_403040, sizeof(v2));
  for ( i = 0; i <= 18; ++i )
  {
    if ( (char)(*(_BYTE *)(i + a1) ^ aHahahahaDoYouF[i]) != v2[i] )
    {
      puts("wrong ~");
      v3 = 0;
      exit(0);
    }
  }
  puts("come here");
  return v3;
}

 

 

aHahahahaDoYouF中的字符串是hahahaha_do_you_find_me?

unk_403040中的字符通过shift + E 可以直接导出

然后写个脚本破解一下

v2 = [14, 13, 9, 6, 19, 5, 88, 86, 62, 6, 12, 60, 31, 87, 20, 107, 87, 89, 13]
xor = 'hahahaha_do_you_find_me?'
flag = []
for i in range(0, 19):
    flag.append(v2[i] ^ ord(xor[i]))
for i in range(0, 19):
    print(chr(flag[i]), end = '')

得到结果是

flag{d07abccf8a410c

flag明显少了一部分啊,但是它最后还有一个

finally函数

int __cdecl sub_40159A(int a1)
{
  unsigned int v1; // eax
  char v3[9]; // [esp+13h] [ebp-15h] BYREF
  int v4; // [esp+1Ch] [ebp-Ch]
​
  strcpy(v3, "%tp&:");
  v1 = time(0);
  srand(v1);
  v4 = rand() % 100;
  v3[6] = 0;
  *(_WORD *)&v3[7] = 0;
  if ( (v3[(unsigned __int8)v3[5]] != *(_BYTE *)((unsigned __int8)v3[5] + a1)) == v4 )
    return puts("Really??? Did you find it?OMG!!!");
  else
    return puts("I hide the last part, you will not succeed!!!");
}

这段代码具体是什么意思真的没搞明白,但是前面的加密算法是异或,所以尝试一下异或

得到的flag现在没有最后一位 },那么剩下的字符串里肯定是最后一个字符异或一个数得到}

flag = [] 
v3 = [37, 116, 112, 38, 58]#既是‘%tp&:’
key = ord('}') ^ 58
for i in range(5):
    flag.append(chr(v3[i] ^ key))
print(''.join(flag))

最后得到

b37a}

flag

flag{d07abccf8a410cb37a}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这个错误是在运行命令"./configure"时出现的。错误提示是"configure: error: /bin/sh ./config.sub /d/project/nc_file_format/hdf5-1.10.6/install/lib failed"。根据引用,这个错误可能是由于找不到或无法执行config.sub文件导致的。 根据引用中的解决方法,你可以尝试用系统中的config.sub文件替换掉当前目录下的config.sub文件。你可以使用以下命令进行替换: mv /home/joy/config/config.sub /home/joy/config/config.sub.bak cp /usr/share/libtool/build-aux/config.sub /home/joy/config/config.sub mv /home/joy/config/config.guess /home/joy/config/config.guess.bak cp /usr/share/libtool/build-aux/config.guess /home/joy/config/config.guess 这样做可以确保你使用的是系统中的config.sub文件,从而解决配置错误。 此外,你也可以使用引用中的命令查找系统中所有的config.sub文件,与你当前目录下的进行比较,以确定是否存在其他引起错误的config.sub文件。你可以使用以下命令进行查找: find / -name config.sub 这会在系统中查找所有名为config.sub的文件,并输出它们的路径。你可以将这些路径与你当前目录下的config.sub进行比较,以找到可能引起错误的文件。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [configure: error: cannot run /bin/bash config/config.sub](https://blog.csdn.net/Jocker_xie/article/details/89332120)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值