| |

VerySource

 Forgot password?
 Register
Search
View: 713|Reply: 5

Bug or am I doing it wrong? ? ?

[Copy link]

1

Threads

4

Posts

4.00

Credits

Newbie

Rank: 1

Credits
4.00

 China

Post time: 2020-1-17 21:20:01
| Show all posts |Read mode
Because I need to use the MD5 algorithm, and I am really lazy, I decided to use the MD5Init, MD5Update, MD5Final API provided by Windows, but Microsoft is also lazy. These three APIs do not even provide header files, so I had to use LoadLibrary. GetProcAddress. But the problem appeared, after the compilation and running prompt:
Run-Time Check Failure # 0-The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
The problem is where MD5Init is called. Disassembly, it was found that when the API function returned, the ret 4 instruction was used (MD5Init has only one parameter: a pointer to the MD5_CTX structure). After returning, it was found that the code generated by VS added an instruction such as Add esp, 4, and ESP was added by mistake. 4 bytes were loaded, so the above problem occurred. But the same code I compile with GCC3.4.4 without problems.
How to solve this problem. The source code is as follows:

//////////////md5.h//////////////////////

#pragma once

#include <windows.h>

typedef struct _MD5_CTX
{
ULONG i [2];
ULONG buf [4];
unsigned char in [64];
unsigned char digest [16];
} MD5_CTX;

typedef void (* PMD5Init) (
MD5_CTX * context
);

typedef void (* PMD5Update) (
MD5_CTX * context,
unsigned char * input,
unsigned int inlen
);

typedef void (* PMD5Final) (
MD5_CTX * context
);

////////////////////////md5.cpp///////////////////
#include "stdafx.h"
#include "md5.h"

void GetMD5Hash (MD5_CTX * md5)
{
HMODULE hmodule = LoadLibrary (TEXT ("Cryptdll.dll"));
PMD5Init MD5Init = (PMD5Init) GetProcAddress (hmodule, "MD5Init");
Ranch
MD5Init (md5); // This is it! !! !!

FreeLibrary (hmodule);
}


int _tmain (int argc, _TCHAR * argv [])
{
MD5_CTX md5;

GetMD5Hash (&md5);

return 0;
}
Reply

Use magic Report

1

Threads

4

Posts

4.00

Credits

Newbie

Rank: 1

Credits
4.00

 China

 Author| Post time: 2020-1-23 12:09:01
| Show all posts
Seems like using stdcall, but how should it be written
Reply

Use magic Report

1

Threads

4

Posts

4.00

Credits

Newbie

Rank: 1

Credits
4.00

 China

 Author| Post time: 2020-1-23 12:54:01
| Show all posts
Done
typedef void (__stdcall * PMD5Init) (
           MD5_CTX * context
);
Reply

Use magic Report

0

Threads

1

Posts

2.00

Credits

Newbie

Rank: 1

Credits
2.00

 China

Post time: 2020-1-23 19:45:01
| Show all posts
Fast. Happy for the landlord.
Reply

Use magic Report

0

Threads

70

Posts

42.00

Credits

Newbie

Rank: 1

Credits
42.00

 China

Post time: 2020-1-24 13:54:01
| Show all posts
Many people have similar problems because of the way they are called, and once again remember that I hope I won't make the same mistake in the future!
Reply

Use magic Report

1

Threads

4

Posts

4.00

Credits

Newbie

Rank: 1

Credits
4.00

 China

 Author| Post time: 2020-1-26 22:18:01
| Show all posts
At the beginning, I checked MSDN for a long time. I didn't know where the __stdcall should be inserted when using typedef. Then I thought it might not be necessary to add it, and the result was wrong. Later I searched on the Internet and found that the difference between cdcel and stdcall is that the caller cleans the stack by the callee. It seems that it is necessary to use stdcall. After thinking about it for a long time, typedef void __stdcall * PMD5Init cannot In this way, typedef void (__stdcall * PMD5Init), as expected, it succeeded this time ~ haha, thank you everyone ~
Reply

Use magic Report

You have to log in before you can reply Login | Register

Points Rules

Contact us|Archive|Mobile|CopyRight © 2008-2023|verysource.com ( 京ICP备17048824号-1 )

Quick Reply To Top Return to the list