两道加载dll函数 的题目 XCTF 3rd-ZCTF-2017 easy-reverse-200 湖湘杯 HighwayHash64

哇 我真的好菜啊 最近心态爆炸了    然后 我这种 密码学不好的人 我本来想自己用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 输入都没有办法输入~~~~

HighwayHash64

这个题目和上面差不多   但是唯一的一点就是这个是exe

然后百度了一波

参考链接的操作是 exe 改成dll   需要修改两处

  • IMAGE_FILE_HEADER->Characteristics(文件属性)->2102h(DLL文件一般是2102h)
  • IMAGE_OPTIONAL_HEADER->AddressOfEntryPoint(程序执行入口RVA)->0000h

 

 

改成 

02 21

 rva

 改成 0 0

然后后缀改成dll  

然后用x64的程序打开    就可以加载函数 然后进行爆破了   

代码就是参考链接的小小改动  = =  用x64编译,,, 原谅我的小小懒惰,,,,

 

#include "pch.h"
#include<Windows.h>
#include <cstdio>

typedef __int64(__fastcall *f)(__int64 buff, unsigned __int64 len);

int main()
{
	HINSTANCE hdll;
	hdll = LoadLibrary(TEXT("reverse.dll"));
	if (hdll == NULL)
	{
		printf("Load dll Error: %d\n", GetLastError());
		return 0;
	}
	printf("Dll base is %llx\n", hdll);

	f func = ((f)((char*)hdll + 0x17A0));

	int i;
	unsigned long long  result;
	for (i = 0; i < 50; i++)
	{
		result = func((long long)&i, 4);
		if (result == 0xD31580A28DD8E6C4)
		{
			printf("Len is %d\n", i - 9);
		}
	}

	unsigned long long j;
	unsigned long long result2;
	char buff[20];
	for (j = 0; j < 10000000000; j++)
	{
		sprintf_s(buff, "%0.10llu", j);
		result2 = func((long long)buff, 10);
		if (result2 == 0xE3BE26AF8730545A)
		{
			printf("flag is %lld\n", j);
			system("pause");
			system("pause");
			return 0;
		}
	}
	return 0;
}

参考链接

https://blog.csdn.net/charlesgodx/article/details/86762347

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值