Re[2]: Принудительный inline
От: TimurSPB Интернет  
Дата: 26.08.09 15:39
Оценка: +1
Здравствуйте, Tilir, Вы писали:

T>Здравствуйте, gribodemon, Вы писали:


G>>Как же заставить компилятор отказаться от call, от прыжков различных (je) — т.е. чтобы он вставлял код функции прямо в код, где она вызывается?


T>Рассмотрите вариант заменить функцию на макрос.


Не слушайте этого человека!
Это ловушка!!!
Make flame.politics Great Again!
Re[3]: Принудительный inline
От: Аноним  
Дата: 26.08.09 15:57
Оценка:
T>>Рассмотрите вариант заменить функцию на макрос.
TSP>Не слушайте этого человека!
TSP>Это ловушка!!!
да нет уж пусть договариват до конца
любопытно стало, как он предлагает вернуть из макроса длину char* строчки, не пользуясь функциями
Re[4]: Принудительный inline
От: Кодт Россия  
Дата: 27.08.09 11:33
Оценка:
Здравствуйте, <Аноним>, Вы писали:

T>>>Рассмотрите вариант заменить функцию на макрос.

TSP>>Не слушайте этого человека!
TSP>>Это ловушка!!!

Луч смерти активирован! Зелёная коробочка!

А>да нет уж пусть договариват до конца

А>любопытно стало, как он предлагает вернуть из макроса длину char* строчки, не пользуясь функциями

#define STRLEN(s) (COUNTOF(s)-1)
#define COUNTOF(s) (sizeof(s) / sizeof((s)[0]))

... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
http://files.rsdn.org/4783/catsmiley.gif Перекуём баги на фичи!
Re[5]: Принудительный inline
От: Аноним  
Дата: 27.08.09 12:41
Оценка:
А>>да нет уж пусть договариват до конца
А>>любопытно стало, как он предлагает вернуть из макроса длину char* строчки, не пользуясь функциями

К>
К>#define STRLEN(s) (COUNTOF(s)-1)
К>#define COUNTOF(s) (sizeof(s) / sizeof((s)[0]))
К>

К>
я просил, char * а не char[], ета хрень всегда будет возвращать 4... Лучше бы уж 42
Re: Принудительный inline
От: gribodemon  
Дата: 27.08.09 12:42
Оценка:
В общем, после долгих попыток написать С++ код, который будет генерировать рабочий шеллкод, я ни к чему не пришел.
На мой взгляд, гораздо проще использовать Relocation Table. В этом случае можно перенести свой код в другое приложение, пофиксить эту Reloc-Table и запускать на исполнение (MS VS -> Project -> Properties -> Configuration Properties -> Linker -> Advanced -> Fixed Base Address -> Generate Relocation table (/FIXED:NO) ).

В общем, респект Great'у за код:

// Get VA
#define RVATOVA( base, offset )(((DWORD)(base) + (DWORD)(offset))) 

// Move program's memory
void __CopyMemoryAcrossProcesses( HANDLE hProcess, char* pMemLocal, char* pMemRemote )
{
    DWORD dwOldProt, dwNumBytes, i;
    MEMORY_BASIC_INFORMATION mbi;
     
    VirtualQueryEx(hProcess, pMemRemote, &mbi, sizeof(MEMORY_BASIC_INFORMATION));
    while (mbi.Protect!=PAGE_NOACCESS && mbi.RegionSize!=0)
    {
        if (!(mbi.Protect & PAGE_GUARD))
        {
            for (i = 0; i < mbi.RegionSize; i += 0x1000)
            {
                VirtualProtectEx(hProcess, pMemRemote + i, 0x1000,PAGE_EXECUTE_READWRITE, &dwOldProt);
                WriteProcessMemory(hProcess, pMemRemote + i, pMemLocal + i, 0x1000, &dwNumBytes);
            }
        }
        pMemLocal += mbi.RegionSize;
        pMemRemote += mbi.RegionSize;
        VirtualQueryEx(hProcess, pMemRemote, &mbi, sizeof(MEMORY_BASIC_INFORMATION));    
    }
}

bool TransferProgram(HANDLE hProcess)
{
    HMODULE g_module = GetModuleHandle(0);
    VirtualFreeEx(hProcess, g_module, 0, MEM_RELEASE);
    
    DWORD dwSize = ((PIMAGE_OPTIONAL_HEADER)((LPVOID)((BYTE *)(g_module) + ((PIMAGE_DOS_HEADER)(g_module))->e_lfanew + 
        sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER))))->SizeOfImage;

    char *pMem = (char *)VirtualAllocEx(hProcess, g_module, dwSize, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    if(pMem == NULL) return FALSE;

    __CopyMemoryAcrossProcesses( hProcess, (char*) g_module, pMem );

    return true;
}

DWORD TransferProgramEx(HANDLE hProcess)
/*
 Return value: image base delta, -1 on error
*/
{
    HMODULE hmodule = GetModuleHandle(0);
    DWORD dwSize = ((PIMAGE_OPTIONAL_HEADER)((LPVOID)((BYTE *)(hmodule) + ((PIMAGE_DOS_HEADER)(hmodule))->e_lfanew + 
        sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER))))->SizeOfImage;

    MEMORY_BASIC_INFORMATION mbi = {0};
    VirtualQueryEx( hProcess, hmodule, &mbi, sizeof(mbi) );

    LPVOID Allocated;

    // Memory isn't free, relocate
    if( mbi.Protect!=PAGE_NOACCESS && mbi.RegionSize!=0 )
    {
__try_relocate:
        LPVOID DesiredAddress = hmodule;
        *(DWORD*)&DesiredAddress += mbi.RegionSize;

        for(;;)
        {
            Allocated = VirtualAllocEx( hProcess, DesiredAddress, dwSize, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE );
            if( Allocated )
                break;
            *(DWORD*)&DesiredAddress += dwSize;
        }
    }
    else
    {
        Allocated = VirtualAllocEx( hProcess, hmodule, dwSize, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE );
        if( !Allocated )
            goto __try_relocate;
    }

    // move memory
    __CopyMemoryAcrossProcesses( hProcess, (char*) hmodule, (char*) Allocated );

    DWORD ImageBaseDelta = (DWORD)Allocated - (DWORD)hmodule;

    // Nonzero imagebase delta
    if( ImageBaseDelta )
    {
        // Apply fixups
        typedef struct 
        {
            WORD    Offset:12;
            WORD    Type:4;
        } IMAGE_FIXUP_ENTRY, *PIMAGE_FIXUP_ENTRY;

        PIMAGE_OPTIONAL_HEADER poh = 
            (PIMAGE_OPTIONAL_HEADER)(
                (DWORD)hmodule
                + ((PIMAGE_DOS_HEADER)hmodule)->e_lfanew
                + sizeof(IMAGE_NT_SIGNATURE)
                + sizeof(IMAGE_FILE_HEADER)
            );

        // No fixups?
        if( !poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress )
        {
            VirtualFreeEx( hProcess, Allocated, dwSize, MEM_DECOMMIT );
            VirtualFreeEx( hProcess, Allocated, dwSize, MEM_RELEASE  );
            return -1;
        }

        PIMAGE_BASE_RELOCATION Reloc = (PIMAGE_BASE_RELOCATION) RVATOVA(poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress, hmodule);
        int i = 0;

        // Process fixups
        for( PIMAGE_FIXUP_ENTRY Fixup = (PIMAGE_FIXUP_ENTRY)( (DWORD)Reloc + sizeof(IMAGE_BASE_RELOCATION) );
             (DWORD)Fixup < (DWORD)Reloc + Reloc->SizeOfBlock -2;
             Fixup ++, i ++
                 )
        {
            if( Fixup->Type == IMAGE_REL_BASED_HIGHLOW )
            {
                DWORD* Patch = (DWORD*)RVATOVA( Reloc->VirtualAddress + Fixup->Offset, Allocated );
                
                DWORD t, r;
                BOOL b = 1;

                // correct fixup
                b &= ReadProcessMemory( hProcess, Patch, &t, 4, &r );
                t += ImageBaseDelta;
                b &= WriteProcessMemory( hProcess, Patch, &t, 4, &r );

                if( !b ) 
                {
                    // smth wrong
                    VirtualFreeEx( hProcess, Allocated, dwSize, MEM_DECOMMIT );
                    VirtualFreeEx( hProcess, Allocated, dwSize, MEM_RELEASE  );
                    return -1;
                }
            }
            else 
            {
                // unsupported fixup type
                VirtualFreeEx( hProcess, Allocated, dwSize, MEM_DECOMMIT );
                VirtualFreeEx( hProcess, Allocated, dwSize, MEM_RELEASE  );
                return -1;
            }
        }
    }

    return ImageBaseDelta;
}


Использовать так:


#include <windows.h>
#include <tlhelp32.h>

VOID InjectFunc () {
    MessageBox(NULL, "Inject is successfull", "!NFA", MB_ICONINFORMATION);
}

VOID main()
{
    HANDLE h = NULL;
    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    if (hSnap != INVALID_HANDLE_VALUE)
    {
        PROCESSENTRY32 pe = {0};
        pe.dwSize = sizeof(pe);
        
        if (Process32First(hSnap, &pe))
            do
            {
                if( !lstrcmpiA(pe.szExeFile, "calc.exe") )
                {
                    h = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);
                    if (h) break;
                }
            }
            while (Process32Next(hSnap, &pe));
            
        CloseHandle(hSnap);
    }
    if (!h) return;

    DWORD ImageBaseDelta = TransferProgramEx( h );

    switch(ImageBaseDelta)
    {
    case -1: {
        MessageBox(NULL, "TransferProgramEx fails!", "ERROR", MB_ICONERROR);
        return;
             }

    case 0:
        MessageBox(NULL, "Program copied at the same addresses", "!NFA", MB_ICONINFORMATION);
        break;

    default:
        MessageBox(NULL, "Program relocated", "!NFA", MB_ICONINFORMATION);
        break;
    }

    DWORD thID;
    HANDLE hTh;

    hTh = CreateRemoteThread( h, 0, 0, (LPTHREAD_START_ROUTINE)((PCHAR)InjectFunc + ImageBaseDelta), 0, 0, &thID);
    WaitForSingleObject( hTh, INFINITE );

    return;
}
reloc table transfer program
Re[4]: Принудительный inline
От: Tilir Россия http://tilir.livejournal.com
Дата: 27.08.09 20:35
Оценка:
Здравствуйте, Аноним, Вы писали:

А>да нет уж пусть договариват до конца

А>любопытно стало, как он предлагает вернуть из макроса длину char* строчки, не пользуясь функциями

static int STRLEN_RESULT_;
#define CALC_STRLEN(str) {STRLEN_RESULT_ = 0; for (; str[STRLEN_RESULT_] != '\0'; STRLEN_RESULT_++);}

int main(void){
  const char *str = "Hello, macros";
  CALC_STRLEN(str);
  std::cout << "strlen(" << str << ") = " << STRLEN_RESULT_ << std::endl;
  getchar();
  return 0;
}
Re[2]: Принудительный inline
От: gear nuke  
Дата: 29.08.09 04:34
Оценка:
Здравствуйте, gribodemon, Вы писали:

G>В общем, после долгих попыток написать С++ код, который будет генерировать рабочий шеллкод, я ни к чему не пришел.


Технически это возможно, но практического смысла не имеет.

G>В общем, респект Great'у за код:


Для простоты, фиксить релоки и связывать импорт (в общем случае это тоже нужно, несмотря на работоспособность примера) можно на копии в своём адресном пространстве, а потом скопировать подготовленный образ в свободное место чужего АП (а не куда попало). Еще проще расшарить секцию между процессами. В общем, код не повод для копипаста.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.