一道困惑很久的题目 XCTF 3rd-ZCTF-2017 easy-reverse-200

哇 我真的好菜啊 最近心态爆炸了    然后 我这种 密码学不好的人 我本来想自己用C语言实现  但是考试临近 就没有办法了

因为密码学不好的我 导致我现在关于密码学的题就会有点不自信  所以 想等暑假实习回来就把网络编程  然后 因为 某个ctf里面的 xtea 还有crc16 我没有看出来   我想练一下xtea的题目  然后,,,,

就遇到了这个题

先看一下 ida 里面的 xtea 

https://blog.csdn.net/gsls200808/article/details/48243019

发现 这里的sum+=  被优化成 -=  然后 其它也大同小异

然后我太过认为这个xtea  是标准的xtea  用了网站 还有python 发现都不行

然后自己心态就崩了

后来一个南邮的大佬学弟和我说是 有所变化的 需要自己实现

晕,,, 还是自己太菜了

反其道实现就可以了

#include <stdio.h>
#include <stdint.h>
typedef unsigned char   uint8;
#define _BYTE  uint8
#define LOBYTE(x)   (*((_BYTE*)&(x)))
void decrypt(int a1, int a2, _BYTE  *input, int key)
{
  int sum; // eax
  char *result; // eax

  sum = (int)input;
  LOBYTE(a2) = *input;
  LOBYTE(a1) = input[1];
  LOBYTE(sum) = 0xD9u;

  do
  {
        sum += 71;
        a1 -= (sum + *(unsigned __int8 *)(key + (((char)sum >> 11) & 3))) ^ (a2 + (16 * (char)a2 ^ ((char)a2 >> 5)));
        a2 -= (a1 + (((char)a1 >> 5) ^ 16 * (char)a1)) ^ (sum + *(unsigned __int8 *)(key + (sum & 3)));
  }
  while ( (_BYTE)sum != 0xB9u );
  result = (char *)input;
  *input = a2;
  input[1] = a1;
  printf("%c%c",input[0],input[1]);
}
int main()
{
    unsigned char key[]={0xde,0xad,0xbe,0xef};
    unsigned char a[]={0xBF, 0xF1, 0x6A, 0x2C, 0x10, 0x0B, 0x16, 0x59, 0xBA, 0x3A,
  0x8C, 0x49, 0x05, 0x1B, 0x04, 0xE2, 0x85, 0xD5, 0xC2, 0xFC,
  0xD7, 0x9B, 0xE9, 0x42};
  int i;
  int v3=0,v4=0;
  for(i=0;i<24;i+=2)
    {
        decrypt(v4, v3, a+i, (int)key);
    }
    return 0;
}

然后这个题目看起来就结束了  但是后来想了想 可以完全导出 dll函数  然后可以实现调试dll函数功能

 说干就干   然后这个题目给了 符号表 完全可以 直接用符号导出

如果没有的话 也可以 句柄加偏移

#include <iostream>
#include <Windows.h>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<iostream>
#include<map>
#include<time.h>
#include<queue>
typedef int(*encrypt_str)(char*, int, int*);
typedef int(*get_string)();
encrypt_str encrypt_strs = NULL;
get_string get_strings = NULL;
char input[50];
int key = 0xEFBEADDE;
unsigned char strs[] = { 0xBF, 0xF1, 0x6A, 0x2C, 0x10, 0x0B, 0x16, 0x59, 0xBA, 0x3A,
0x8C, 0x49, 0x05, 0x1B, 0x04, 0xE2, 0x85, 0xD5, 0xC2, 0xFC,
0xD7, 0x9B, 0xE9, 0x42 };
HMODULE hdll = NULL;
int main()
{
	hdll = ::LoadLibrary(TEXT("C:\\Users\\Lenovo\\Desktop\\CTF\\ctf3.dll"));
	if(hdll==NULL)
	{
		printf("dll加载失败!\n");
		::FreeLibrary(hdll);
	}
	else
	{
		printf("%0x\n", hdll);
		//encrypt_strs=(encrypt_str)((int)hdll + 0x127C)
		encrypt_strs = (encrypt_str)GetProcAddress(hdll, "encrypt_str");
		get_strings = (get_string)::GetProcAddress(hdll, "get_string");
		if(get_strings==NULL)
		{
			printf("调用get_string函数失败!\n");
		}
		else
		{
			get_strings();
			printf("成功!\n");
		}
		if(encrypt_strs==NULL)
		{
			printf("加载运行函数失败!\n");
			::FreeLibrary(hdll);
			free(encrypt_strs);
		}
		else
		{
			scanf("%s", input);
			encrypt_strs(input, strlen(input)+1, &key);
			printf("%s\n", input);

		}
	}
}

然后就可以用od 调试这个函数了

 虽然 od也可以直接拉近dll  但是总感觉没有这样写好 这样自己实现也方便

直接拉的话 dll 输入都没有办法输入~~~~

猜你喜欢

转载自blog.csdn.net/qq_41071646/article/details/91976020