Visual C++ 在函数末尾附加 0xCC (int3) 字节

这是我第一次来,我真的希望你们能帮助我,因为我现在已经没有想法了.

This is my first time around, and I really hope you guys can help me, as I have ran out of ideas by now.

我已经搜索了几个小时的答案,但找不到实际可行的答案.

I have searched for an answer for a couple of hours now, and could not find an answer that would actually work.

我想直接将代码注入正在运行的进程中.是的,你没有看错.我正在尝试将代码注入另一个应用程序,并且 - 不管你信不信 - 这只是为了扩展它的功能.

I would like to directly inject code into a running process. Yes, you have read it right. I am trying to inject code into another application, and - believe it or not - this is only to extend the functionality of it.

我在 Windows 上使用 Visual Studio 2012 Express Edition.

I am using Visual Studio 2012 Express Edition on Windows.

我有以下代码:

__declspec(naked) void Foo()
{
    __asm
    {
        // Inline assembly code here
    }
}
__declspec(naked) void FooEnd() {}

int main()
{
    cout << HEX(Foo) << endl;
    cout << HEX(FooEnd) <<  endl;
    cout << (int)FooEnd - (int)Foo << endl;

    // Inject code here using WriteProcessMemory

    return 0;
}

为了保持可读性,大部分代码已被删除,但我可以根据要求发布其他部分.

Most of the code has been removed in order to maintain readability, though I can post other portions of it on request.

输出如下:

0x010B1000
0x010B1010
16

结果大小实际上是不正确的.这些函数以正确的顺序编译(确保使用/ORDER),但是编译器在每个扩展其大小的方法之后添加了一堆 0xCC(int 3)字节,所以我无法获得真正的(有用的)数字包含实际可执行代码的字节数.

The resulting size is actually incorrect. The functions are compiled in the right order (made sure using /ORDER), but the compiler adds a bunch of 0xCC (int 3) bytes after each method which extends it's size, and so I can't get the real (useful) number of bytes that contains actual executable code.

在另一个 stackoverflow 问题中,据说禁用编辑并继续"会使这些额外的字节消失,但无论如何,这对我不起作用.

In another stackoverflow question, it has been said that disabling "Edit and Continue" would make these extra bytes go away, but no matter what, that didn't work for me.

我也尝试使用 Release setup 而不是 Debug,更改了一堆优化设置,但这些都没有任何效果.您认为可能的解决方案是什么?我可能遗漏了一些明显的东西.

I also tried using Release setup instead of Debug, changed a bunch of optimization settings, but none of these had any effect. What do you think could be the solution? I may be missing something obvious.

无论如何,这是(在您看来)获取函数长度(可读性、可靠性、易用性)的最佳方式吗?

Anyway, is this (in your opinion) the best way to acquire a function's length (readability, reliability, ease of use)?

我希望我解释了我必须做的一切,以便您能够提供帮助.如果您还有其他问题,请随时发表评论.

I hope I explained everything I had to in order for you to be able to help. If you have further questions, please feel free to leave a comment.

感谢您的时间和努力.

推荐答案

在注入代码时不需要额外的填充,因此可以丢弃它们.复制它们也应该没问题,它只会导致复制一些额外的字节.无论如何,您注入的内存可能会被页面对齐的块所占用,因此通过剥离它您并没有真正获得任何东西.

You don't need the extra padding when you're injecting the code, so it's fine to discard them. It should also be fine to copy them over, it will just result in a few extra bytes of copying. Chances are the memory you're injecting to will by a page-aligned block anyway, so you're not really gaining anything by stripping it out.

但是如果你真的想去掉它,一个简单的解决你的问题的方法是从下一个函数之前的最后一个字节向后迭代,直到没有更多的 0xcc 字节.

But if you really want to strip it out, a simple solution to your problem would be to just iterate backwards from the last byte before the next function, until there are no more 0xcc bytes.

即:

__declspec(naked) void Foo()
{
   __asm
   {
      _emit 0x4A
      _emit 0x4B
   }
}
__declspec(naked) void FooEnd() {}


int main(int argc, char** argv)
{
   //start at the last byte of the memory-aligned code instead of the first byte of FooEnd
   unsigned char* fooLast = (unsigned char*)FooEnd-1;

   //keep going backwards until we don't have a 0xcc
   while(*fooLast == 0xCC)
      fooLast--;

   //fooLast will now point at the last byte of your function, so you need to add 1
   int length = ((int)fooLast - (int)Foo) + 1;

   //should output 2 for the length of Foo
   std::cout << length;
}

相关文章