一道困惑很久的题目 XCTF 3rd-ZCTF-2017 easy-reverse-200
程序员文章站
2022-05-15 19:21:14
...
哇 我真的好菜啊 最近心态爆炸了 然后 我这种 密码学不好的人 我本来想自己用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 输入都没有办法输入~~~~
上一篇: 封装