首页
社区
课程
招聘
[原创]模拟windwos系统调用例子,重写writeprocessmemory和readprocessmemory
发表于: 2022-2-12 13:37 16061

[原创]模拟windwos系统调用例子,重写writeprocessmemory和readprocessmemory

2022-2-12 13:37
16061

分别以int21和syscall两种调用方式实现 代码如下

志同道合的小伙伴们可以加群一起交流技术,共同进步 788518452

#include "stdafx.h"
#include <Windows.h>
 
// 读进程内存(中断门调用)
BOOL WINAPI HbgReadProcessMemory_INT(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead)
{
    LONG NtStatus;
    __asm
    {
        // 直接模拟 KiIntSystemCall
        lea edx,hProcess; // 要求 edx 存储最后入栈的参数
        mov eax, 0xBA;
        int 0x2E;
        mov NtStatus, eax;
    }
    if (lpNumberOfBytesRead != NULL)
    {
        *lpNumberOfBytesRead = nSize;       
    }
    // 错误检查
    if (NtStatus < 0)
    {
        return FALSE;
    }
    return TRUE;
}
 
// 读进程内存(快速调用)
BOOL WINAPI HbgReadProcessMemory_FAST(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead)
{
 
    LONG NtStatus;
    /*
    __asm
    {
        // 模拟 ReadProcessMemory
        lea eax,nSize;
        push eax;
        push nSize;
        push lpBuffer;
        push lpBaseAddress;
        push hProcess;
        sub esp, 0x04; // 模拟 ReadProcessMemory 里的 CALL NtReadVirtualMemory
        // 模拟 NtReadVirtualMemory
        mov eax, 0xBA;
        push NtReadVirtualMemoryReturn; // 模拟 NtReadVirtualMemory 函数里的 CALL [0x7FFE0300]
        // 模拟 KiFastSystemCall
        mov edx, esp;
        _emit 0x0F; // sysenter
        _emit 0x34;
NtReadVirtualMemoryReturn:       
        add esp, 0x18; // 模拟 NtReadVirtualMemory 返回到 ReadProcessMemory 时的 RETN 0x14
        mov NtStatus, eax;
    }
    if (lpNumberOfBytesRead != NULL)
    {
        *lpNumberOfBytesRead = nSize;       
    }
    */
    __asm
    {
        lea eax,nSize;
        push eax;
        push nSize;
        push lpBuffer;
        push lpBaseAddress;
        push hProcess;
        sub esp, 0x04; // 模拟 ReadProcessMemory 里的 CALL NtReadVirtualMemory
        // 模拟 NtReadVirtualMemory
        mov eax, 0xBA;
        mov edx, 0X7FFE0300   //不能直接调用内核,间接call函数地址来实现
        CALL DWORD PTR[EDX]
        add esp, 0x18;
        mov NtStatus, eax;
    }
    // 错误检查
    if (NtStatus < 0)
    {
        return FALSE;
    }
    return TRUE;
}
 
// 写进程内存(中断门调用)
BOOL WINAPI HbgWriteProcessMemory_INT(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesWritten)
{
    LONG NtStatus;
    __asm
    {
        lea edx,hProcess;
        mov eax, 0x115;
        int 0x2E;
        mov NtStatus, eax;
    }
    if (lpNumberOfBytesWritten != NULL)
    {
        *lpNumberOfBytesWritten = nSize;       
    }
    // 错误检查
    if (NtStatus < 0)
    {
        return FALSE;
    }
    return TRUE;
}
 
// 写进程内存(快速调用)
BOOL WINAPI HbgWriteProcessMemory_FAST(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesWritten)
{
    LONG NtStatus;
    __asm
    {
        // 模拟 WriteProcessMemory
        lea eax,nSize;
        push eax;
        push nSize;
        push lpBuffer;
        push lpBaseAddress;
        push hProcess;
        sub esp, 0x04; // 模拟 WriteProcessMemory 里的 CALL NtWriteVirtualMemory
        // 模拟 NtWriteVirtualMemory
        mov eax, 0x115;
/*
push NtWriteVirtualMemoryReturn; // 模拟 NtWriteVirtualMemory 函数里的 CALL [0x7FFE0300]
        // 模拟 KiFastSystemCall
        mov edx, esp;
        _emit 0x0F; // sysenter
        _emit 0x34;
NtWriteVirtualMemoryReturn:       
*/
        mov edx, 0X7FFE0300   //不能直接调用内核,间接call函数地址来实现
            CALL DWORD PTR[EDX]
        add esp, 0x18; // 模拟 NtWriteVirtualMemory 返回到 WriteProcessMemory 时的 RETN 0x14
        mov NtStatus, eax;
    }
    if (lpNumberOfBytesWritten != NULL)
    {
        *lpNumberOfBytesWritten = nSize;       
    }
    // 错误检查
    if (NtStatus < 0)
    {
        return FALSE;
    }
    return TRUE;
}
 
void __declspec(naked) MyReadMem(HANDLE hProcess,LPVOID addr,LPVOID buffer,DWORD len, LPDWORD lpNumberOfBytesWritten)
{
    _asm
    {
        mov   eax, 0BAh
        mov   edx, 7FFE0300h
        call  dword ptr[edx]
 
        ret 0x14
    }
}
 
 
BOOL WINAPI HbgReadProcessMemory_FAST2(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead)
{
 
    LONG NtStatus;
 
    __asm
    {
        lea eax,nSize;
        push eax;
        push nSize;
        push lpBuffer;
        push lpBaseAddress;
        push hProcess;
        call MyReadMem
    }
    // 错误检查
    if (NtStatus < 0)
    {
        return FALSE;
    }
    return TRUE;
}
HANDLE WINAPI MyOpenProcess(
    __in DWORD dwDesiredAccess,
    __in BOOL bInheritHandle,
    __in DWORD dwProcessId
    )
{
    __asm
    {
        mov   eax, 07Ah
        mov   edx, 7FFE0300h
        call  dword ptr[edx]
 
        ret 0x10
    }
}
 
HANDLE WINAPI OpenProcessSub(
    __in DWORD dwDesiredAccess,
    __in BOOL bInheritHandle,
    __in DWORD dwProcessId
    )
{
    return 0;
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    int nTmp = 200;   
    int nValue = 100;
 
    HbgWriteProcessMemory_FAST(INVALID_HANDLE_VALUE,&nValue,&nTmp,sizeof(int),0);
    HbgReadProcessMemory_FAST(INVALID_HANDLE_VALUE,&nValue,&nTmp,sizeof(int),NULL);
    HbgReadProcessMemory_FAST2(INVALID_HANDLE_VALUE,&nValue,&nTmp,sizeof(int),NULL);
    HANDLE hProcess1 = OpenProcess(  PROCESS_ALL_ACCESS, false, 2972 ); 
    HANDLE hProcess2 = MyOpenProcess(  PROCESS_ALL_ACCESS, false, 2972 ); 
    return 0;
}
#include "stdafx.h"
#include <Windows.h>
 
// 读进程内存(中断门调用)
BOOL WINAPI HbgReadProcessMemory_INT(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead)
{
    LONG NtStatus;
    __asm
    {
        // 直接模拟 KiIntSystemCall
        lea edx,hProcess; // 要求 edx 存储最后入栈的参数
        mov eax, 0xBA;
        int 0x2E;
        mov NtStatus, eax;
    }
    if (lpNumberOfBytesRead != NULL)
    {
        *lpNumberOfBytesRead = nSize;       
    }
    // 错误检查
    if (NtStatus < 0)
    {
        return FALSE;
    }
    return TRUE;
}
 
// 读进程内存(快速调用)
BOOL WINAPI HbgReadProcessMemory_FAST(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead)
{
 
    LONG NtStatus;
    /*
    __asm
    {
        // 模拟 ReadProcessMemory
        lea eax,nSize;
        push eax;
        push nSize;
        push lpBuffer;
        push lpBaseAddress;
        push hProcess;
        sub esp, 0x04; // 模拟 ReadProcessMemory 里的 CALL NtReadVirtualMemory
        // 模拟 NtReadVirtualMemory
        mov eax, 0xBA;
        push NtReadVirtualMemoryReturn; // 模拟 NtReadVirtualMemory 函数里的 CALL [0x7FFE0300]
        // 模拟 KiFastSystemCall
        mov edx, esp;
        _emit 0x0F; // sysenter
        _emit 0x34;
NtReadVirtualMemoryReturn:       
        add esp, 0x18; // 模拟 NtReadVirtualMemory 返回到 ReadProcessMemory 时的 RETN 0x14
        mov NtStatus, eax;
    }
    if (lpNumberOfBytesRead != NULL)
    {
        *lpNumberOfBytesRead = nSize;       
    }
    */
    __asm
    {
        lea eax,nSize;
        push eax;
        push nSize;
        push lpBuffer;
        push lpBaseAddress;
        push hProcess;
        sub esp, 0x04; // 模拟 ReadProcessMemory 里的 CALL NtReadVirtualMemory
        // 模拟 NtReadVirtualMemory
        mov eax, 0xBA;
        mov edx, 0X7FFE0300   //不能直接调用内核,间接call函数地址来实现
        CALL DWORD PTR[EDX]
        add esp, 0x18;
        mov NtStatus, eax;
    }
    // 错误检查
    if (NtStatus < 0)
    {
        return FALSE;
    }
    return TRUE;
}
 
// 写进程内存(中断门调用)
BOOL WINAPI HbgWriteProcessMemory_INT(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesWritten)
{
    LONG NtStatus;
    __asm
    {
        lea edx,hProcess;
        mov eax, 0x115;
        int 0x2E;
        mov NtStatus, eax;
    }
    if (lpNumberOfBytesWritten != NULL)
    {
        *lpNumberOfBytesWritten = nSize;       
    }
    // 错误检查
    if (NtStatus < 0)
    {
        return FALSE;
    }
    return TRUE;
}
 
// 写进程内存(快速调用)
BOOL WINAPI HbgWriteProcessMemory_FAST(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesWritten)
{

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 5
支持
分享
最新回复 (5)
雪    币: 6076
活跃值: (5480)
能力值: ( LV5,RANK:65 )
在线值:
发帖
回帖
粉丝
2
感谢分享,看到这里面有一些地址是硬编码,是不是对系统有针对性?
2022-2-16 18:18
0
雪    币: 2540
活跃值: (4829)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
gamehack 感谢分享,看到这里面有一些地址是硬编码,是不是对系统有针对性?
是的
2022-2-17 11:48
0
雪    币: 14806
活跃值: (6043)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
冒昧问一下,目的何在?
2022-2-17 14:17
0
雪    币: 2948
活跃值: (30846)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
感谢分享
2023-11-24 10:11
1
雪    币: 30050
活跃值: (2422)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6

很早以前玩过了,syscall,目的是anti那些hook了ntdll.dll的杀软,但实质上现在很多杀软都是直接hook了int来检测,具体方法网上文章也很多。


另外,序列号最好是实时根据PE文件格式进行计算,而不是使用硬编码:

procedure ParseServiceIDs; stdcall;
var
     Table: TStringList;
begin
     Table := BuildSysCallTable();//根据PE文件格式计算序列号表
try
     _DuplicateObject := StrToInt(Table.Values['NtDuplicateObject']);
     _TerminateProcess := StrToInt(Table.Values['NtTerminateProcess']);
     _TerminateThread := StrToInt(Table.Values['NtTerminateThread']);
     _QueueApcThread := StrToInt(Table.Values['NtQueueApcThread']);
     _GetThreadContext := StrToInt(Table.Values['NtGetContextThread']);
     _OpenProcess := StrToInt(Table.Values['NtOpenProcess']);
     _OpenThread := StrToInt(Table.Values['NtOpenThread']);
     _QueryInfoProcess := StrToInt(Table.Values['NtQueryInformationProcess']);
     _QueryInfoThread := StrToInt(Table.Values['NtQueryInformationThread']);
     _ReadProcessMemory := StrToInt(Table.Values['NtReadVirtualMemory']);
     _SuspendProcess := StrToInt(Table.Values['NtSuspendProcess']);
     _ResumeProcess := StrToInt(Table.Values['NtResumeProcess']);
     _CloseHandle := StrToInt(Table.Values['NtClose']);
     _QueryVirtualMemory := StrToInt(Table.Values['NtQueryVirtualMemory']);
     _ProtectVirtualMemory := StrToInt(Table.Values['NtProtectVirtualMemory']);
     _WriteVirtualMemory := StrToInt(Table.Values['NtWriteVirtualMemory']);
     _FlushICache := StrToInt(Table.Values['NtFlushInstructionCache']);
     _SuspendThread := StrToInt(Table.Values['NtSuspendThread']);
     _ResumeThread := StrToInt(Table.Values['NtResumeThread']);
     _ShutdownSystem := StrToInt(Table.Values['NtShutdownSystem']);
     _LoadDriver := StrToInt(Table.Values['NtLoadDriver']);
     _UnloadDriver := StrToInt(Table.Values['NtUnloadDriver']);
     _QuerySysInfo := StrToInt(Table.Values['NtQuerySystemInformation']);
     _QueryObject := StrToInt(Table.Values['NtQueryObject']);
     _SetInfoThread := StrToInt(Table.Values['NtSetInformationThread']);
     _TestAlert := StrToInt(Table.Values['NtTestAlert']);
     _AllocVirtualMem := StrToInt(Table.Values['NtAllocateVirtualMemory']);
     _FreeVirtualMem := StrToInt(Table.Values['NtFreeVirtualMemory']);
     _FsControlFile := StrToInt(Table.Values['NtFsControlFile']);
     _DevIoControlFile := StrToInt(Table.Values['NtDeviceIoControlFile']);
     _WaitForSingleObject := StrToInt(Table.Values['NtWaitForSingleObject']);
     _CreateRemoteThread := StrToInt(Table.Values['NtCreateThreadEx']);
     _NtCreateFile := StrToInt(Table.Values['NtCreateFile']);
finally
     Table.Free();
     STACK_CLEANUP := AdjustStack();
end;

计算过程其实也很简单:

  if PWORD(pExpName)^ = $744E {Nt} then
    begin
    result.Values[String(AnsiString(pExpName))] := IntToStr(PDWORD(
                                                            DWORD(ULONG_PTR(pBase) +
                                                            DWORD(PDWORD(ULONG_PTR(pBase) +
                                                            DWORD(pExp^.AddressOfFunctions) +
                                                            WORD(PWORD(ULONG_PTR(pBase) +
                                                            DWORD(pExp^.AddressOfNameOrdinals) + i * 2)^) * 4)^)) + dwOffset)^);
         end;

网上也有文章介绍配合符号文件来计算的,这种实际使用中就不大现实了。

上传的附件:
2023-11-24 15:07
0
游客
登录 | 注册 方可回帖
返回
//