虚拟文件系统设计

时间:2012-03-22 17:54:35

标签: c++ debugging assembly low-level packer

我正在启动一个类似项目的保护者/打包者/活页夹。

目标是当你有一个完整的应用程序目录

  • /图像/
  • /音乐/
  • base * .ini files
  • 的DLL
  • 组价

您只需在其上使用packer.exe,所有这些文件都会打包,加密并存储在生成的exe文件中。

生成的exe然后会创建一个透明的虚拟文件系统,如果找不到文件,它将回退到“真实”文件系统。

我已经可以处理(不是非常准确)从内存加载dll等,但我有一个hmm钩子的问题..

现在,作为ProofOfConcept我将debbuger(用c ++编写)附加到target.exe

看起来有点像

======= Started [target.exe] =======
> Placing breakpoint on EP : 0x401130
Process started
Loaded module : [target.exe]
Loaded module : [ntdll.dll]
Loaded module : [kernel32.dll]
[...]
Break point at [0x401130]
 > Restored EP byte.
 Loaded module : [bass.dll]
Break point at [0x760fcc4e]
Found set bp : kernel32!CreateFileW
[!] CreateFileW Callback Function :
       FileName : C:\Users\user\Desktop\cppve\loader\bin\Debug\target.exe
       Access   : 0x80000000
       Return Addr: 0x741b91e6
 > Re-setting bp at [0x760fcc4e]
Break point at [0x760fcc4e]
Found set bp : kernel32!CreateFileW
[!] CreateFileW Callback Function :
       FileName : .\beyond_v.mod
       Access   : 0x80000000
       Return Addr: 0x760fcfa0

我正在调试器中处理断点,例如CreateFileW ReadFile等 我在向目标提供可用数据时遇到问题。

我应该创建一个假手柄,然后抓住并处理它?或者有太多东西可以用这种方法出错?

这是CreateFileW的示例回调函数

void callback_createfilew(CONTEXT* ct){
//stub
cout<<"[!] CreateFileW Callback Function :"<<endl;

void* returnaddr=MemReadDwordPtr(hProcess,(void*)ct->Esp);
string fn=MemReadCString(hProcess,MemReadDwordPtr(hProcess,(void*)ct->Esp+4),true);
void* access=MemReadDwordPtr(hProcess,(void*)ct->Esp+8);
void* sharemode=MemReadDwordPtr(hProcess,(void*)ct->Esp+12);
void* dwCreationDisposition=MemReadDwordPtr(hProcess,(void*)ct->Esp+20);
void* dwFlagsAndAttributes=MemReadDwordPtr(hProcess,(void*)ct->Esp+24);

cout<<"       FileName : "<<fn<<endl;
cout<<"       Access   : "<<(void*)access<<endl;
cout<<"       Return Addr: "<<(void*)returnaddr<<endl;

if(fn.compare(".\\beyond_v.mod")==0){
    // this is wrong, we need to call it from the target process...
    HANDLE ret=CreateFileA(".\\_beyond_v.mod",(DWORD)access,(DWORD)sharemode,NULL,(DWORD)dwCreationDisposition,(DWORD)dwFlagsAndAttributes,NULL);
    ct->Esp+=0x20;
    ct->Eax=(DWORD)ret;
    ct->Eip=(DWORD)returnaddr;
}

我应该在流程中进行编解码并推送shellcodes [编辑:对不起,我用这些词来描述不同的东西,但我想你会抓住我的想法:)] 那里执行我的伪造代码?

或者可能注入一个将处理int3并通过加载程序设置的异常处理程序将控制传递给它的DLL?然而,这可能是棘手的...... dll必须在虚拟文件系统中!所以我必须在任何其他初始化之前手动加载它。

我想在最终版本中完全删除调试器。它只会引起问题并严重影响项目的保护部分。

1 个答案:

答案 0 :(得分:1)

如果你希望你的“打包器”在预编译的二进制文件上透明地操作并希望所有内容都在生成的单个二进制文件中,那么打包器需要将挂钩代码添加到二进制文件中,这可能会使它作为第一件事而只执行然后将控制权传递给二进制文件的原始入口点。这不是很微不足道,虽然肯定是可行的。

但你这里有另一个问题。这个挂钩代码将包含解密代码,也可能包含密钥,这一切都可以通过一个带有调试器和其他工具的优秀程序员来解决。

对于假句柄,我会看到是否可以多次打开文件并获得不同的句柄。如果是,只需打开任何现有文件以便在共享模式下读取,请记住该句柄并将其用于内存文件。需要另一个手柄?再次打开文件以获得一个。这样可以保证不与其他真正的手柄发生碰撞。