简体   繁体   English

C ++ memcpy()棘手的用法,需要了解行为

[英]C++ memcpy() tricky use, behavior understanding needed

Decompilation so as to fix an old program can be painful. 反编译以修复旧程序可能很痛苦。

As I'm a C# developer, there's something strange I don't understand. 因为我是C#开发人员,所以有一些我不理解的怪现象。 I would need a C++ tricks expert to help me understand the behaviour of "memcpy()". 我需要一名C ++技巧专家来帮助我了解“ memcpy()”的行为。

Here's what I play with: 这是我玩的东西:

unsigned char sdata[] =  { 0x54, 
                           ... many values (=4100) ..., 
                           0x00 };

then 然后

unsigned char BF_PTransformed[4*18] = { 0xC6, 
                                    ... many values (=72) ..., 
                                        0x7B };

and

struct BLOWFISH_CTX 
{
  unsigned long P[16 + 2];
  unsigned long S[4][256];
};

Here are the memcpy() calls: 以下是memcpy()调用:

void BFInit() 
{
    BLOWFISH_CTX* ctx = &this->BlowfishContext; 

    memcpy((void*)ctx->P, this->BF_PTransformed, 18*4);
    memcpy((void*)ctx->S, (void*)this->sdata, 0x100*4*4);
}

Questions 问题

I do not understand how this behaves with higher number of bytes than arrays destination length. 我不明白这种行为在字节数大于数组目标长度时的行为。 Is that about data types? 那是关于数据类型的吗?

Can someone explain it so it can be understood by a C# developer? 有人可以解释它,以便C#开发人员可以理解吗?

(And do not even try to mention the word Blowfish. 2 days on this "special" implementation made me sick ahah) (甚至不要提河豚一词。这种“特殊”实施的2天让我恶心了啊哈)

The memcpy length parameter is in bytes not array elements. memcpy length参数的单位是字节,而不是数组元素。

The code would be better written as: 最好将代码编写为:

memcpy((void*)ctx->P, this->BF_PTransformed, 18 * sizeof(unsigned long));
memcpy((void*)ctx->S, (void*)this->sdata, 0x100 * 4 * sizeof(unsigned long));

I do not undestand how does behave this with higher number of bytes than arrays destination length Is that about data types ? 我不明白如何使用比数组目标长度更多的字节数来实现这一点?这与数据类型有关吗?

First, memcpy operates on bytes, not array elements. 首先, memcpy对字节进行操作,而不对数组元素进行操作。 So if you want to copy an array int[10] , for example, you tell memcpy to copy 40 bytes ( 10*sizeof(int) ). 因此,例如,如果您要复制一个数组int[10] ,则告诉memcpy复制40个字节( 10*sizeof(int) )。 So the argument passed to memcpy (40 in this example) can be greater than the number of array elements (10), because each array element takes up more than one byte. 因此,传递给memcpy的参数(在此示例中为40)可以大于数组元素的数量(10),因为每个数组元素占用一个以上的字节。

Second, if you genuinely tell memcpy to copy past the end of the array (say, if we passed 43 as the argument to memcpy in the above example), then you would have undefined behavior . 其次,如果您真的告诉memcpy复制了数组的末尾(例如,如果我们在上面的示例中将43作为参数传递给memcpy ),那么您将有undefined behavior

In C and C++, many error conditions are not required to be detected at compiletime or runtime. 在C和C ++中,不需要在编译时运行时检测到许多错误情况。 In C#, an exception would be thrown if you tried something illegal at runtime. 在C#中,如果您在运行时尝试了非法操作,则将引发异常。

In C++, that happens in some cases too. 在C ++中,这种情况发生在某些情况下也。 But in many others, the error isn't detected at all, and what happens is undefined . 但是在许多其他情况下,根本无法检测到该错误,并且发生的情况不确定 The application may crash, or it may continue to running in a corrupted state. 该应用程序可能会崩溃,或者可能继续以损坏的状态运行。 It may become a security vulnerability, or it may (in theory) make demons fly out of your nose. 它可能成为安全漏洞,或者(理论上)可能使恶魔从您的鼻子中飞出。 The language spec simply says nothing about what should happen. 语言规范根本没有提到要发生什么。

And reading past the end of an array (as you'd do if you tell memcpy to copy more than the length of the array) is one such occasion. 读完数组末尾(如果您告诉memcpy要复制的长度大于数组的长度,您会这样做)就是这样一种情况。 If you try to do it, your application has a bug, but there's no saying how it will behave when you try to run it. 如果您尝试执行此操作,则您的应用程序会出现错误,但是并没有说明您尝试运行它时的行为。 If you're lucky , it'll crash. 如果幸运的话 ,它会崩溃。 In the worst case, it'll continue running, because then it'll be in an inconsistent state, and it might crash later (making the error much harder to diagnose), or it might, instead of crashing, simply produce the wrong results, or it may appear to work correctly when you run it on your computer, but exhibit any of these behaviors when your customer runs your application. 在最坏的情况下,它将继续运行,因为它会处于不一致状态,并且可能稍后崩溃(使错误更难以诊断),或者可能不是崩溃而是仅产生错误结果,或者当您在计算机上运行它时,它似乎可以正常工作,但是当客户运行您的应用程序时,则表现出上述任何一种行为。

Undefined behavior is bad. 未定义的行为是不好的。 Avoid at all costs. 不惜一切代价避免。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM