吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2559|回复: 19
收起左侧

[CrackMe] 矛与盾----第一个反调试程序

[复制链接]
镇北看雪 发表于 2020-3-13 11:33
CM是什么?Crackme是什么?这是什么东西?楼主发的什么?
他们都是一些公开给别人尝试破解的小程序,制作 Crackme 的人可能是程序员,想测试一下自己的软件保护技术,也可能是一位 Cracker,想挑战一下其它 Cracker 的破解实力,也可能是一些正在学习破解的人,自己编一些小程序给自己破解,KeyGenMe是要求别人做出它的 keygen (序号产生器), ReverseMe 要求别人把它的算法做出逆向分析, UnpackMe 是要求别人把它成功脱壳,本版块禁止回复非技术无关水贴。

本帖最后由 镇北看雪 于 2020-3-13 16:22 编辑

masm32写的一个反调试的程序




非常抱歉第一次上传的文件有一个bug,我修复了(浪费了大家的币抱歉!)
过几天我会把原码以及思路公开

注册成功的消息框:(不要在意消息框的标题,我只是在MessageBox时没有设置消息框的标题栏而已)

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册[Register]

x

免费评分

参与人数 3吾爱币 +8 热心值 +3 收起 理由
古月不傲 + 1 + 1 我很赞同!
CrazyNut + 6 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
tianshu44 + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

赤座灯里 发表于 2020-3-14 03:58
本帖最后由 赤座灯里 于 2020-3-14 05:21 编辑

[C] 纯文本查看 复制代码
int i = 0;
char *code="tu shan shan";
char *str;
int ret = 0;
__int16 tmp;
do {
        str[i] = username[i] + (username[i] ^ code[i]);
        ++i;
}
while ( i != strlen(code));
i = 0;
int len = strlen(str);
do {
        LOBYTE(tmp) = str[i];
        int m = i + 1;
        HIBYTE(tmp) = tmp ^ str[m];
        i = m + 1;
        if ( i <= len ) {
                str[i] ^= HIBYTE(tmp);
                LOBYTE(tmp) = 0;
        }
        LOWORD(ret) = tmp + ret;
}
while ( i <= len );
if ( ret == 521 ) {
        *(_DWORD *)&str[v4 + 184] -= 41;
        Text = 115;
        byte_403005 = 117;
        byte_403006 = 99;
        byte_403007 = 99;
        byte_403008 = 101;
        byte_403009 = 115;
        byte_40300A = 115;
        //这里将0x403004赋值为success
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册[Register]

x

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
镇北看雪 + 1 + 1 我很赞同!

查看全部评分

古月不傲 发表于 2020-3-15 02:45
本帖最后由 古月不傲 于 2020-3-15 03:04 编辑

[C] 纯文本查看 复制代码
LONG __stdcall TopLevelExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo)
{
  unsigned int v2; // eax
  unsigned int v3; // ecx
  unsigned int v4; // kr04_4
  int v5; // edx
  int v6; // eax
  __int16 v7; // bx

  if ( ExceptionInfo->ExceptionRecord->ExceptionFlags == 1 )
    return 0;
  if ( ExceptionInfo->ExceptionRecord->ExceptionCode != -1073741676 )
    return 0;
  ExceptionInfo->ContextRecord->Eip += 2;
  v2 = 0;
  v4 = strlen(byte_403024) + 1;
  v3 = v4 - 1;
  v5 = 0;
  do
  {
    LOBYTE(v7) = byte_403024[v2];
    v6 = v2 + 1;
    HIBYTE(v7) = v7 ^ byte_403024[v6];
    v2 = v6 + 1;
    if ( v2 <= v3 )
    {
      byte_403024[v2] ^= HIBYTE(v7);
      LOBYTE(v7) = 0;
    }
    LOWORD(v5) = v7 + v5;
  }
  while ( v2 <= v3 );
  if ( v5 == 521 )
  {
    *(_DWORD *)&byte_403024[v4 + 184] -= 41;
    Text = 115;
    byte_403005 = 117;
    byte_403006 = 99;
    byte_403007 = 99;
    byte_403008 = 101;
    byte_403009 = 115;
    byte_40300A = 115;
  }
  return -1;
}


感谢你的上一篇贴子 巩固了我的知识

一开始我是想ZwQueryInformationProcess 但是我修改的是eax 不是输出的缓冲区 我搞错了
[C] 纯文本查看 复制代码
#include <ntifs.h>
#include <ntddk.h>

ULONG g_uOldZwQueryInformationProcess = 0;

//系统服务描述符表
#pragma push(1)
typedef struct ServiceDescriptorEntry {
	unsigned int *ServiceTableBase;          //系统服务表基址
	unsigned int *ServiceCounterTableBase;	 //系统服务表被调用的次数
	unsigned int NumberOfServices;           //系统服务表函数个数
	unsigned char *ParamTableBase;           //系统服务表函数参数大小 (字节)
}ServiceDescriptorTableEntry, *PServiceDescriptorTableEntry;
#pragma pop(1)

__declspec(dllimport) ServiceDescriptorTableEntry KeServiceDescriptorTable;

typedef NTSTATUS (NTAPI *PNewZwQueryInformationProcess)(
	_In_      HANDLE           ProcessHandle,
	_In_      PROCESSINFOCLASS ProcessInformationClass,
	_Out_     PVOID            ProcessInformation,
	_In_      ULONG            ProcessInformationLength,
	_Out_opt_ PULONG           ReturnLength
);

typedef enum _xp {
	DebugPort = 0xbc,
	Flink = 0x88,
	Blink = 0x8c,
	ImageFileName = 0x174
}xp;

typedef struct _Timer {
	KTIMER ktimer;
	KDPC kdpc;
	PEPROCESS pEprocess;
}Timer, *pTimer;

Timer timer = { 0 };

// 关闭cr0读写位
void Cr0WpOff()
{
	__asm
	{
		cli
		mov  eax, cr0
		and  eax, not 10000h
		mov  cr0, eax
	}
}

// 开启cr0读写位
void Cr0WpOn()
{
	__asm
	{
		mov  eax, cr0
		or eax, 10000h
		mov  cr0, eax
		sti
	}
}

VOID DriverUnload(PDRIVER_OBJECT pDriverObject) {

	//KeCancelTimer(&timer.ktimer);
	Cr0WpOff();
	KeServiceDescriptorTable.ServiceTableBase[0x9A] = g_uOldZwQueryInformationProcess;
	Cr0WpOn();
}

//获取进程对象
PEPROCESS GetProcess() {

	PEPROCESS pCurrentProcess;
	PEPROCESS pNextProcess;
	pCurrentProcess = PsGetCurrentProcess();
	pNextProcess = (PEPROCESS)((*(PULONG)((ULONG)pCurrentProcess + Flink)) - Flink);
	while (pNextProcess != pCurrentProcess) {
		//KdPrint(("%s\n", ((PUCHAR)pNextProcess + ImageFileName)));
		if (strcmp((PUCHAR)pNextProcess + ImageFileName, "safe.exe") == 0) {
			KdPrint(("找到了 safe.exe进程\n"));
			return pNextProcess;
		}
		pNextProcess = (PEPROCESS)((*(PULONG)((ULONG)pNextProcess + Flink)) - Flink);
	}
	return NULL;
}

VOID DpcProduct(
	_In_     struct _KDPC *Dpc,
	_In_opt_ PVOID        DeferredContext,
	_In_opt_ PVOID        SystemArgument1,
	_In_opt_ PVOID        SystemArgument2
)
{
	pTimer pt = (pTimer)DeferredContext;
	LARGE_INTEGER time;
	time.QuadPart = -3000;
	*(PULONG)((ULONG)pt->pEprocess + DebugPort) = 0;
	KeSetTimer(&pt->ktimer, time, &pt->kdpc);
}

NTSTATUS NewZwQueryInformationProcess(
	_In_      HANDLE           ProcessHandle,
	_In_      PROCESSINFOCLASS ProcessInformationClass,
	_Out_     PVOID            ProcessInformation,
	_In_      ULONG            ProcessInformationLength,
	_Out_opt_ PULONG           ReturnLength
	) 
{
	__asm 
	{
		mov eax, 1
	}
	return ((PNewZwQueryInformationProcess)g_uOldZwQueryInformationProcess)(
		ProcessHandle,
		ProcessInformationClass,
		ProcessInformation,
		ProcessInformationLength,
		ReturnLength
		);
}

//Hook入口
VOID HookKiFastCallEntry()
{
	Cr0WpOff();
	// 保存原来的ZwQueryInformationProcess
	g_uOldZwQueryInformationProcess = KeServiceDescriptorTable.ServiceTableBase[0x9A];
	// 设置新的ZwQueryInformationProcess
	KeServiceDescriptorTable.ServiceTableBase[0x9A] = (ULONG32)NewZwQueryInformationProcess;
	Cr0WpOn();
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pStrRegPath) {

	pDriverObject->DriverUnload = DriverUnload;
	PEPROCESS pSafeProcess;
	LARGE_INTEGER time;
	time.QuadPart = -3000;
	pSafeProcess = GetProcess();
	KdPrint(("%x\n", pSafeProcess));
	KdPrint(("%x\n", *(PULONG)((ULONG)pSafeProcess + DebugPort)));

	HookKiFastCallEntry();

	/*timer.pEprocess = pSafeProcess;
	KeInitializeTimer(&timer.ktimer);
	KeInitializeDpc(&timer.kdpc, DpcProduct, &timer);*/
	//KeSetTimer(&timer.ktimer, time, &timer.kdpc);
	
	return STATUS_SUCCESS;
}




 楼主| 镇北看雪 发表于 2020-3-14 00:10

其实我把一部分序列号算法放在了异常处理程序中
古月不傲 发表于 2020-3-13 15:44
这种 SetUnhandledExceptionFilter要怎么过呢 难道只能自己写异常处理函数 暂时没找到思路
JuncoJet 发表于 2020-3-13 16:08

大概,把这个 f,修改成 00

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册[Register]

x
JuncoJet 发表于 2020-3-13 16:11

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册[Register]

x
 楼主| 镇北看雪 发表于 2020-3-13 16:20

不是吧,你这只是让他本来显示fail变成什么都不显示了。
正确注册的消息框显示一个success
头像被屏蔽
庞晓晓 发表于 2020-3-13 16:22
提示: 作者被禁止或删除 内容自动屏蔽
JuncoJet 发表于 2020-3-13 16:25
镇北看雪 发表于 2020-3-13 16:20
不是吧,你这只是让他本来显示fail变成什么都不显示了。
正确注册的消息框显示一个success

好吧,那我错了
Leroy840923533 发表于 2020-3-13 18:13
不错,谢谢分享
t00t00 发表于 2020-3-13 22:05
貌似把部分运算放在了Exception中。

循环次数大于字符串长度不知道会返回空还是报错。
头像被屏蔽
China华夏 发表于 2020-3-13 22:33
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-25 01:20

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表