hasherezade / pe_to_shellcode

Converts PE into a shellcode
https://www.youtube.com/watch?v=WQCiM0X11TA
BSD 2-Clause "Simplified" License
2.39k stars 433 forks source link

run shellcode.exe in dll faild #13

Closed july0426 closed 4 years ago

july0426 commented 4 years ago

我把你的runsh.exe.修改成dll,通过dll运行生成的shellcode,有时会失败,也不报错,会卡住,有的时候可以,不知道这是为什么

hasherezade commented 4 years ago

can you share the sample of the generated shellcode, so that I can see where it gets stuck?

july0426 commented 4 years ago
#include "pch.h"
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <atlstr.h>
#include <tchar.h>
#include <windows.h>
#include <winnt.h>
#include <winternl.h>
#include <peconv.h>
#include<stdio.h>
#include <io.h>
#include<vector>
#include <direct.h>
#define MAX_PATH 280

using namespace std;

void getFiles(string path, string path2, vector<string>& files)
{
    //文件句柄  
    intptr_t   hFile = 0;
    //文件信息  
    struct _finddata_t fileinfo;
    string p, p2;
    if ((hFile = _findfirst(p.assign(path).append(path2).append("*").c_str(), &fileinfo)) != -1)
    {
        do
        {

            if ((fileinfo.attrib &  _A_SUBDIR))
            {
                if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
                    getFiles(p.assign(path).append("\\"), p2.assign(fileinfo.name).append("\\"), files);
            }
            else
            {
                files.push_back(p.assign(path2).append(fileinfo.name));  
                //files.push_back(p.assign(fileinfo.name) );   
            }
        } while (_findnext(hFile, &fileinfo) == 0);
        _findclose(hFile);
    }
}

std::string Find_exename() {
    LPTSTR pCommandLine;

    pCommandLine = GetCommandLine();
    _tprintf(L"%s\n", pCommandLine);
    CString sChar = CString(pCommandLine);
    USES_CONVERSION;
    std::string exe_name1 = std::string(T2A(sChar));

    std::string cmd = exe_name1.substr(0, exe_name1.find(".exe") + 4);
    cout << cmd << endl;

    string exe_name = cmd.substr(cmd.find_last_of("\\") + 1);

    //cout << exe_name << endl;

    char   buffer[MAX_PATH];
    _getcwd(buffer, MAX_PATH);
    cout << buffer << endl;

    CString filePath;
    GetModuleFileName(NULL, filePath.GetBufferSetLength(MAX_PATH + 1), MAX_PATH);
    filePath.ReleaseBuffer();
    int pos = filePath.ReverseFind('\\');
    filePath = filePath.Left(pos);

    string filePath2;
    filePath2 = CT2A(filePath.GetString());
    vector<string> files;
    filePath2.assign(buffer).append("\\");

    getFiles(filePath2, "", files);
    int size = files.size();
    //cout << size << endl;
    string load_name = "";
    for (int i = 0; i < size; i++)
    {
        //cout << files[i].c_str() << endl;
        string filename = files[i].c_str();
        //cout << filename.length() << endl;
        //cout << filename.find_last_of(".dll") << endl;
        if (filename.length() - filename.find_last_of(".dll") == 1) {
            continue;
        };
        if (filename == exe_name) {
            continue;
        };
        if (filename.length() - filename.find_last_of(".exe") == 1) {
            load_name = filename;
            break;
        };

    }
    return load_name;
}

int Load_ShellCode() {
    //string load_name = "mishc.exe";
    string load_name = Find_exename();
    char* in_path = (char*)load_name.data();

    std::cout << "[*] Reading module from: " << in_path << std::endl;

    size_t exe_size = 0;
    BYTE *my_exe = peconv::load_file(in_path, exe_size);
    if (!my_exe) {
        std::cout << "[-] Loading file failed" << std::endl;
        return -1;
    }
    BYTE *test_buf = peconv::alloc_aligned(exe_size, PAGE_EXECUTE_READWRITE);
    if (!test_buf) {
        peconv::free_file(my_exe);
        std::cout << "[-] Allocating buffer failed" << std::endl;
        return -2;
    }
    //copy file content into executable buffer:
    memcpy(test_buf, my_exe, exe_size);

    //free the original buffer:
    peconv::free_file(my_exe);
    my_exe = nullptr;

    std::cout << "[*] Running the shellcode:" << std::endl;
    //run it:
    int(*my_main)() = (int(*)()) ((ULONGLONG)test_buf);
    int ret_val = my_main();

    peconv::free_aligned(test_buf, exe_size);
    //std::cout << "[+] The shellcode finished with a return value: " << std::hex << ret_val << std::endl;
    return ret_val;
}

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    Load_ShellCode();
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:

    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

这是我用来生成dll的代码,只是修改了自动寻找shellcode的部分,加载的部分没有修改,不知道为什么执行不成功,我可以给你邮件发送shellcode吗,文件有点大

july0426 commented 4 years ago

https://github.com/july0426/tags_count_pngtree/raw/master/frpc.shc.exe

hasherezade commented 4 years ago

does you shellcode run fine when it is executed with the original "runshc.exe"? does it fail only with the modified version, or with both?

hasherezade commented 4 years ago

can you share the application that was converted to the shellcode? I will have to check it. maybe there was a problem with the conversion. you can send me an email: hasherezade@pm.me

july0426 commented 4 years ago

runshc.exe是可以执行成功的,改写的dll执行有些shellcode也是可以成功的,但是有些就会失败

hasherezade commented 4 years ago

ok, please send me an e-mail with all the components necessary to reproduce the error, and I will check. the first thing that I see in your code which may cause problems:

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)

    Load_ShellCode(); // <- will be run multiple times, and it may cause problems
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:

    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

try this:

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        Load_ShellCode(); //<- should be run once: on attach only
        return TRUE;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
july0426 commented 4 years ago

已经该你发送邮件了

hasherezade commented 4 years ago

I will check it in details today in the evening, when I will get some free time.

july0426 commented 4 years ago

十分感谢!!!

july0426 commented 4 years ago

我想我知道原因了,如果shellcode中需要创建新线程,就会导致失败,可能跟多线程死锁有关

hasherezade commented 4 years ago

Sorry, I didn't have a time to check it, I was working on a new release of one of my project. I will check it for sure in upcoming days. But yes, it may be related to threading issues. Did you try to change the DllMain to this?

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        Load_ShellCode(); //<- should be run once: on attach only
        return TRUE;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
july0426 commented 4 years ago

修改了,按照你的方法,但是没有奏效

hasherezade commented 4 years ago

sorry for the delay, I was busy with my work. today I checked your code and I made some modifications. I tested it and it should work. you will find it here: rushc_dll

in general, you should not run the shellcode in DllMain, but instead, do it from an exported function (I named it run) https://github.com/hasherezade/pe_to_shellcode/blob/4e7c3b36e8b554cdf13e7019c1806a965f0d1ec7/runshc_dll/main.cpp#L123-L142

Please let me know if it solves your problem.

hasherezade commented 4 years ago

How to run it:

runshc_dll_runner.exe <name of the shellode module>

run_shc

hasherezade commented 4 years ago

Try the build:

runshc_dll.zip

july0426 commented 4 years ago

谢谢你的帮助,我尝试了一下,确实ok了