矛与盾----第一个反调试程序
本帖最后由 镇北看雪 于 2020-3-13 16:22 编辑masm32写的一个反调试的程序
非常抱歉第一次上传的文件有一个bug,我修复了(浪费了大家的币抱歉!)
过几天我会把原码以及思路公开
注册成功的消息框:(不要在意消息框的标题,我只是在MessageBox时没有设置消息框的标题栏而已)
本帖最后由 赤座灯里 于 2020-3-14 05:21 编辑
int i = 0;
char *code="tu shan shan";
char *str;
int ret = 0;
__int16 tmp;
do {
str = username + (username ^ code);
++i;
}
while ( i != strlen(code));
i = 0;
int len = strlen(str);
do {
LOBYTE(tmp) = str;
int m = i + 1;
HIBYTE(tmp) = tmp ^ str;
i = m + 1;
if ( i <= len ) {
str ^= HIBYTE(tmp);
LOBYTE(tmp) = 0;
}
LOWORD(ret) = tmp + ret;
}
while ( i <= len );
if ( ret == 521 ) {
*(_DWORD *)&str -= 41;
Text = 115;
byte_403005 = 117;
byte_403006 = 99;
byte_403007 = 99;
byte_403008 = 101;
byte_403009 = 115;
byte_40300A = 115;
//这里将0x403004赋值为success
}
本帖最后由 古月不傲 于 2020-3-15 03:04 编辑
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;
v6 = v2 + 1;
HIBYTE(v7) = v7 ^ byte_403024;
v2 = v6 + 1;
if ( v2 <= v3 )
{
byte_403024 ^= HIBYTE(v7);
LOBYTE(v7) = 0;
}
LOWORD(v5) = v7 + v5;
}
while ( v2 <= v3 );
if ( v5 == 521 )
{
*(_DWORD *)&byte_403024 -= 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 不是输出的缓冲区 我搞错了
#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
moveax, cr0
andeax, not 10000h
movcr0, eax
}
}
// 开启cr0读写位
void Cr0WpOn()
{
__asm
{
moveax, cr0
or eax, 10000h
movcr0, eax
sti
}
}
VOID DriverUnload(PDRIVER_OBJECT pDriverObject) {
//KeCancelTimer(&timer.ktimer);
Cr0WpOff();
KeServiceDescriptorTable.ServiceTableBase = 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;
// 设置新的ZwQueryInformationProcess
KeServiceDescriptorTable.ServiceTableBase = (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:05
你们谁 破解了?
其实我把一部分序列号算法放在了异常处理程序中 这种 SetUnhandledExceptionFilter要怎么过呢 难道只能自己写异常处理函数 暂时没找到思路
大概,把这个 f,修改成 00 JuncoJet 发表于 2020-3-13 16:11
不是吧,你这只是让他本来显示fail变成什么都不显示了。
正确注册的消息框显示一个success 镇北看雪 发表于 2020-3-13 16:20
不是吧,你这只是让他本来显示fail变成什么都不显示了。
正确注册的消息框显示一个success
好吧,那我错了 不错,谢谢分享 貌似把部分运算放在了Exception中。
循环次数大于字符串长度不知道会返回空还是报错。
https://s1.ax1x.com/2020/03/13/8KqQ6x.png
页:
[1]
2