镇北看雪 发表于 2020-3-13 11:33

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

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

masm32写的一个反调试的程序




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

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

赤座灯里 发表于 2020-3-14 03:58

本帖最后由 赤座灯里 于 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 02:45

本帖最后由 古月不傲 于 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:10

古月不傲 发表于 2020-3-14 00:05
你们谁 破解了?

其实我把一部分序列号算法放在了异常处理程序中

古月不傲 发表于 2020-3-13 15:44

这种 SetUnhandledExceptionFilter要怎么过呢 难道只能自己写异常处理函数 暂时没找到思路

JuncoJet 发表于 2020-3-13 16:08


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

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

镇北看雪 发表于 2020-3-13 16:20

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


不是吧,你这只是让他本来显示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中。

循环次数大于字符串长度不知道会返回空还是报错。
https://s1.ax1x.com/2020/03/13/8KqQ6x.png

China华夏 发表于 2020-3-13 22:33

页: [1] 2
查看完整版本: 矛与盾----第一个反调试程序