sha256.dll の使用

フォロー:sha256.dll の問題解消 - BiBoLoG

静的リンク以外の手段で「外部 DLL を利用する」のは初めてだ.今やっと,ひしだまさんの記録で関数利用までの手順が分かった.sha256.dll は void *data の SHA-256 ハッシュを計算する.

main.cpp

#include <stdio.h>
#include <windows.h>

typedef HANDLE (WINAPI *FUNC_CreateAlgorithm)(void);
typedef DWORD (WINAPI *FUNC_DestroyAlgorithm)( HANDLE hAlgorithm );
typedef DWORD (WINAPI *FUNC_InitAlgorithm)( HANDLE hAlgorithm );
typedef DWORD (WINAPI *FUNC_InputData)( HANDLE hAlgorithm, const void *data, int length );
typedef DWORD (WINAPI *FUNC_GetHashLength)( HANDLE hAlgorithm );
typedef DWORD (WINAPI *FUNC_GetHash)( HANDLE hAlgorithm, void *buffer, int bufsize );
typedef DWORD (WINAPI *FUNC_GetHashTextLength)( HANDLE hAlgorithm );
typedef DWORD (WINAPI *FUNC_GetHashText)( HANDLE hAlgorithm, char *buffer, int bufsize );

// ハッシュを文字列表示
const char* hex = "0123456789abcdef";
void printHash_sha256(const byte *hash, int hashsize)
{
	for(int i = 0; i < hashsize; i++)
	{
		printf("%c", hex[ (hash[i] >> 4) ]);
		printf("%c", hex[ (hash[i] & 0x0f) ]);
	}
	puts("");
}

// dll 読込とかに失敗したとき実行
void printError(const char *name, int err)
{
	LPVOID lpMsgBuf;
	FormatMessage(
		FORMAT_MESSAGE_ALLOCATE_BUFFER |
		FORMAT_MESSAGE_FROM_SYSTEM |
		FORMAT_MESSAGE_IGNORE_INSERTS,
		NULL,
		err,
		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
		(char*)&lpMsgBuf,
		0,
		NULL
	);
	printf("%s: %d:%s\n", name, err, lpMsgBuf);
	LocalFree(lpMsgBuf);
}

// sha256.dll 使用テスト
int testUseLibrary(void)
{
	// dll 読込
	LPCTSTR lpFileName = "sha256.dll";
	HMODULE hModule = LoadLibrary(lpFileName);
	if (hModule == NULL) {
		printError("LoadLibrary", GetLastError());
		return -1;
	}

	// dll アドレス取得
	FUNC_CreateAlgorithm CreateAlgorithm = (FUNC_CreateAlgorithm)GetProcAddress(hModule, "CreateAlgorithm");
	FUNC_DestroyAlgorithm DestroyAlgorithm = (FUNC_DestroyAlgorithm)GetProcAddress(hModule, "DestroyAlgorithm");
	FUNC_InitAlgorithm InitAlgorithm   = (FUNC_InitAlgorithm)GetProcAddress(hModule, "InitAlgorithm");
	FUNC_InputData InputData = (FUNC_InputData)GetProcAddress(hModule, "InputData");
	FUNC_GetHashLength GetHashLength = (FUNC_GetHashLength)GetProcAddress(hModule, "GetHashLength");
	FUNC_GetHash GetHash  = (FUNC_GetHash)GetProcAddress(hModule, "GetHash");
	FUNC_GetHashTextLength GetHashTextLength = (FUNC_GetHashTextLength)GetProcAddress(hModule, "GetHashTextLength");
	FUNC_GetHashText GetHashText = (FUNC_GetHashText)GetProcAddress(hModule, "GetHashText");

	char *data = "aaaaaaaaaamlfgs;m";
	int length = sizeof(data);

	// dll 内部関数 使用
	// 使用開始
	HANDLE hAlgorithm = CreateAlgorithm();
	if ( hAlgorithm )
	{
		// 初期化
		if ( 0 == InitAlgorithm( hAlgorithm ) )
		{
			// ハッシュを求めたいデータを入力
			if ( 0 == InputData( hAlgorithm, data, length ) )
			{
				// GetHash,GetHashText に必要な length を取得
				const int hashsize = GetHashLength( hAlgorithm );
				const int s_hashsize = GetHashTextLength( hAlgorithm );
				if ( 0 < hashsize && 0 < s_hashsize)
				{
					// メモリ確保
					void *buffer = malloc( hashsize );
					char *s_buffer = (char *)malloc( s_hashsize * sizeof(char) );
					if ( buffer && s_buffer )
					{
						// data の SHA-256 ハッシュを取得
						if ( 0 == GetHash( hAlgorithm, buffer, hashsize ) 
							&&  0 == GetHashText( hAlgorithm, s_buffer, s_hashsize  ))
						{
							puts((char *)buffer); // char * とみなして強引に表示
							puts(s_buffer); // ハッシュ文字列を表示
							printHash_sha256((byte *)buffer, hashsize);
						}
					}
				}
			}
		}

		// 破棄
		if ( 0 != DestroyAlgorithm( hAlgorithm ) )
		{
			printError("FreeLibrary", GetLastError());
			return -2;
		}
	}

	// dll 解放
	if (!FreeLibrary(hModule)){
		printError("FreeLibrary", GetLastError());
		return -3;
	}

	return 0;
}

// 外部 DLL 呼び出しテスト
BOOL testLoadLibrary(void)
{
	LPCTSTR lpFileName = "sha256.dll";
	HMODULE hModule = LoadLibrary(lpFileName);

	LPCSTR lpProcName = "CreateAlgorithm";
	GetProcAddress(hModule, lpProcName);

	lpProcName = "DestroyAlgorithm";
	GetProcAddress(hModule, lpProcName);

	lpProcName = "InitAlgorithm";
	GetProcAddress(hModule, lpProcName);

	lpProcName = "InputData";
	GetProcAddress(hModule, lpProcName);

	lpProcName = "GetHashText";
	GetProcAddress(hModule, lpProcName);

	// http://msdn.microsoft.com/ja-jp/library/cc429103.aspx
	// 関数が成功すると、0 以外の値が返ります。
	// 関数が失敗すると、0 が返ります。拡張エラー情報を取得するには、 関数を使います。
	BOOL result = FreeLibrary(hModule);
	return result;
}

int main(void)
{
	/* 外部 DLL sha256.dll 読込テスト */
	//printf("%d\n", testLoadLibrary());

	/* 外部 DLL sha256.dll 使用テスト */
	printf("%d\n", testUseLibrary());

	return 0;
}

出力

ィUセa盒ン・rロヨ・伊)?澳ホ^エ{ンンンン
61be55a8e2f6b4e172338bddf184d6dbee29c98853e0a0485ecee7f27b9af0b
a855be61e1b4f6e2dd8b3372dbd684f188c929ee48a0e053f2e7ce5eb4f09a7b
0

DLL ファイル名を間違えると,

LoadLibrary: 126:指定されたモジュールが見つかりません。

-1

困ったこと

GetHash() したら,読み込んだデータは byte[] とみなして良いだろうと思って printHash_sha256() を書いたけれど,GetHashText() の結果と異なっている.桁数も違う.