zoukankan      html  css  js  c++  java
  • BHO 透过IE9 保护模式 反IE9保护模式动态库导入表注入 当然反注入不是只能应用到这里,根据不同的注入方案反注入也不同

    BHO插件工作虽然权限已经足够过,不过很多时候还会因为IE9本身影响BHO运行,比如BHO启动外部进程,或者BHO中访问网络,都同样受到保护模式的限制,

    前段时间对于保护模式工作特征进行了DEBUG追踪发现,保护模式主要是由IEShims.dll完成。

    IE进程首先加载IEShims.dll,然后注册NTDLL.dll提供的LibraryLoad通知,然后在其余任何动态库进行加载的时候注入动态库的导入表,然后接核心函数,比如GetProcAddress然后再IEShims.dll实现的GetProcAddress函数内进行了部分功能屏蔽,做到限制其他动态库反注入。以及接管一些IO函数和进程线程相关的核心函数,以便于在合时时候选择弹出提示让用户确认是否运行,不过很多时候这个确实很烦人。

    GetProcAddress对于注入来说非常重要,虽然保护模式接管了它,但是我们也可以自己实现他的功能,动态库的句柄(动态库在内存影射的起始地址),既然句柄为起始地址,完全可以通过这个起始地址根据PE文件结构找到动态库的导入表, 同样也可以找到导出表。

    这个时候完全可以获得kernel32.dll的句柄计算出GetProcAddress函数的导出地址,然后找到自己动态库的的导入表中GetProcAddress函数修改掉被保护模式注入的地址。恢复GetProcAddress函数,那么后续可以在使用GetProcAddress函数恢复其他函数的地址。就可以完成反注入。即刻在让你的BHO插件在保护模式下自由工作。

     1 DWORD MySimpleGetProcAddress(HANDLE hIns,LPSTR funcName)
    2 {
    3 LPBYTE imageBase=NULL;
    4 DWORD result=NULL;
    5
    6 PIMAGE_DOS_HEADER tmpdosHead=NULL;//PE DOS头
    7 PIMAGE_NT_HEADERS tmpntHead=NULL;//PE NT头
    8 PIMAGE_EXPORT_DIRECTORY tmpExport;//导出表
    9 LPDWORD tmpFirstExport=NULL;
    10 LPDWORD tmpFirstName=NULL;
    11 LPWORD tmpFirstOrder=NULL;
    12
    13 LPSTR libName=NULL;
    14 HANDLE tmphInst=NULL;
    15 LPVOID tmpPoint=NULL;
    16 tmphInst=hIns;
    17 tmpdosHead=(PIMAGE_DOS_HEADER)tmphInst;//PE DOS头
    18 tmpntHead=(PIMAGE_NT_HEADERS)((LPBYTE)tmphInst+tmpdosHead->e_lfanew);//PE NT头
    19 tmpExport=(PIMAGE_EXPORT_DIRECTORY)((LPBYTE)tmphInst+tmpntHead->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);//导出表
    20 tmpFirstExport=(LPDWORD)(tmpntHead->OptionalHeader.ImageBase+tmpExport->AddressOfFunctions);
    21 tmpFirstOrder=(LPWORD)(tmpntHead->OptionalHeader.ImageBase+tmpExport->AddressOfNameOrdinals);
    22 tmpFirstName=(LPDWORD)(tmpntHead->OptionalHeader.ImageBase+tmpExport->AddressOfNames);
    23
    24 for(DWORD count=0;count<tmpExport->NumberOfNames;count++)
    25 {
    26
    27 if(strcmp( (LPSTR)(tmpntHead->OptionalHeader.ImageBase+*(tmpFirstName+count)),funcName)==0)
    28 {
    29 tmpPoint=(LPVOID)(tmpntHead->OptionalHeader.ImageBase+tmpFirstExport[tmpFirstOrder[count]]);
    30 if(tmpPoint!=NULL)
    31 {
    32 result=(DWORD)tmpPoint;
    33 break;
    34 }
    35 }
    36 }
    37 return result;
    38 }
    if(hIns==NULL)
    {
    hIns=GetModuleHandleA("NFIEPlugin");//获取当前模块句柄
    }
    LPBYTE imageBase=NULL;
    PIMAGE_DOS_HEADER dosHead=NULL;//PE DOS头
    PIMAGE_NT_HEADERS ntHead=NULL;//PE NT头
    PIMAGE_DATA_DIRECTORY importTableDataDir=NULL;//导入表
    PIMAGE_IMPORT_DESCRIPTOR importDesc=NULL;//导入描述(单个动态库相关)
    PIMAGE_THUNK_DATA32 funPointThunk=NULL;//函数地址链
    PIMAGE_THUNK_DATA32 funNameThunk=NULL;//函数名称链
    PIMAGE_IMPORT_BY_NAME funName=NULL;


    PIMAGE_DOS_HEADER tmpdosHead=NULL;//PE DOS头
    PIMAGE_NT_HEADERS tmpntHead=NULL;//PE NT头
    PIMAGE_EXPORT_DIRECTORY tmpExport;//导出表
    LPDWORD tmpFirstExport=NULL;
    LPDWORD tmpFirstName=NULL;
    LPWORD tmpFirstOrder=NULL;

    LPSTR libName=NULL;
    HANDLE tmphInst=NULL;
    LPVOID tmpPoint=NULL;
    DWORD oldProtect=0;
    if(IsBadReadPtr(hIns,sizeof(IMAGE_DOS_HEADER)))//检测地址有效性
    return FALSE;
    dosHead=(PIMAGE_DOS_HEADER)hIns;
    ntHead=(PIMAGE_NT_HEADERS)((LPBYTE)hIns+dosHead->e_lfanew);
    if(IsBadReadPtr(ntHead,sizeof(IMAGE_NT_HEADERS)))//检测地址有效性
    return FALSE;
    if(ntHead->FileHeader.Machine!=IMAGE_FILE_MACHINE_I386&&ntHead->FileHeader.Machine!=IMAGE_FILE_MACHINE_AMD64)
    {
    return FALSE;//不支持
    }
    if(ntHead->FileHeader.SizeOfOptionalHeader<=0)
    {
    return FALSE;//无可选头则不包含导入表
    }
    *(LPDWORD)&Kernel32GetProcAddress=(DWORD)MySimpleGetProcAddress(LoadLibraryA("kernel32.dll"),"GetProcAddress");
    imageBase=(LPBYTE)ntHead->OptionalHeader.ImageBase;
    PIMAGE_DATA_DIRECTORY dataDir=&ntHead->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; //获取导入表
    importDesc=(PIMAGE_IMPORT_DESCRIPTOR)(imageBase+dataDir->VirtualAddress);

    while(importDesc->Characteristics!=0)
    {
    libName=(LPSTR)(imageBase+importDesc->Name);
    if(strlen(libName)==0)
    {
    continue;
    }
    //获取句柄
    tmphInst=GetModuleHandleA(libName);
    if(tmphInst==NULL)
    tmphInst=LoadLibraryA(libName);
    if(libName==NULL)
    continue;

    tmpdosHead=(PIMAGE_DOS_HEADER)tmphInst;//PE DOS头
    tmpntHead=(PIMAGE_NT_HEADERS)((LPBYTE)tmphInst+tmpdosHead->e_lfanew);//PE NT头
    tmpExport=(PIMAGE_EXPORT_DIRECTORY)((LPBYTE)tmphInst+tmpntHead->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);//导出表
    tmpFirstExport=(LPDWORD)(tmpntHead->OptionalHeader.ImageBase+tmpExport->AddressOfFunctions);
    tmpFirstOrder=(LPWORD)(tmpntHead->OptionalHeader.ImageBase+tmpExport->AddressOfNameOrdinals);
    tmpFirstName=(LPDWORD)(tmpntHead->OptionalHeader.ImageBase+tmpExport->AddressOfNames);

    for(DWORD count=0;count<tmpExport->NumberOfNames;count++)
    {
    //得到名称指针和函数地址指针
    funPointThunk=(PIMAGE_THUNK_DATA32)(imageBase+importDesc->FirstThunk);
    funNameThunk=(PIMAGE_THUNK_DATA32)(imageBase+importDesc->OriginalFirstThunk);
    while(funPointThunk->u1.AddressOfData!=0&&funNameThunk->u1.AddressOfData!=0)
    {

    funName=(PIMAGE_IMPORT_BY_NAME)(imageBase+funNameThunk->u1.AddressOfData);
    if(IsBadReadPtr(funName,4))
    break;
    if(strcmp( (LPSTR)(tmpntHead->OptionalHeader.ImageBase+*(tmpFirstName+count)),(LPSTR)&funName->Name[0])==0)
    {
    /*if(funName->Hint+tmpExport->Base<tmpExport->NumberOfNames)
    {
    */
    tmpPoint=(LPVOID)(tmpntHead->OptionalHeader.ImageBase+tmpFirstExport[tmpFirstOrder[count]]);
    /* }
    else
    {
    tmpPoint=(LPVOID)(tmpntHead->OptionalHeader.ImageBase+tmpFirstExport[tmpFirstOrder[funName->Hint]]);
    }
    */
    if(tmpPoint!=NULL)
    {
    VirtualProtect(funPointThunk,4,PAGE_EXECUTE_WRITECOPY,&oldProtect);
    funPointThunk->u1.AddressOfData=(DWORD)Kernel32GetProcAddress(tmphInst,(LPSTR)funName->Name);;
    VirtualProtect(funPointThunk,4,oldProtect,&oldProtect);
    }
    }

    funPointThunk=funPointThunk+1;
    funNameThunk=funNameThunk+1;
    }
    }
    importDesc=importDesc+1;
    }
    }

    首先恢复GetProcAddress函数,因为上边我自己写的获取导出地址的函数存在BUG不能保证每个函数都能获取正确,不过GetProcAddress肯定会获取对的,也没有精神研究具体的原因,因为恢复GetProcAddress后我就可以不用那个函数了。


     

  • 相关阅读:
    Pytorch中的torch.nn类
    form表单转化json对象
    js 算法
    vue 中ref 的使用注意事项
    url 地址含参数较多如何拼接
    关于jsonp知识的理解
    ztree 使用心得
    Git查看与修改用户名、邮箱(转载)
    vue2.0 keep-alive 最佳实战(转载)
    使用keep-alive 实现 页面回退不刷新内容
  • 原文地址:https://www.cnblogs.com/a185771876/p/2350844.html
Copyright © 2011-2022 走看看