C++: AHK source code: Base64Get/Base64Put and HexGet/HexPut

Talk about things C/C++, some related to AutoHotkey
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

C++: AHK source code: Base64Get/Base64Put and HexGet/HexPut

Post by jeeswg » 19 May 2019, 18:52

Here is some code for some potential Base64Get/Base64Put and HexGet/HexPut functions. They are based on StrGet/StrPut.

Code: Select all

==================================================

for AHK v1: function names and parameters:

cf. StrGet(Address [, Length] [, Encoding := None])
HexGet(Address, Length, Case := "U")
Base64Get(Address, Length)

cf. StrPut(String [, Encoding := None])
cf. StrPut(String, Address [, Length] [, Encoding := None])
HexPut(String)
HexPut(String, Address [, Length])
Base64Put(String)
Base64Put(String, Address [, Length])

- note: for XXXPut functions, there is a question over what 'Length' should mean
- note: the functions require that wincrypt.h be included
- note: perhaps instead, machine code could do the conversions

==================================================

[script.h]

BIF_DECL(BIF_Base64Get);
BIF_DECL(BIF_Base64Put);
BIF_DECL(BIF_HexGet);
BIF_DECL(BIF_HexPut);

==================================================

[script.cpp]

	else if (!_tcsicmp(func_name, _T("Base64Get")))
	{
		bif = BIF_Base64Get;
		min_params = 2;
		max_params = 2;
	}
	else if (!_tcsicmp(func_name, _T("Base64Put")))
	{
		bif = BIF_Base64Put;
		min_params = 1;
		max_params = 3;
	}
	else if (!_tcsicmp(func_name, _T("HexGet")))
	{
		bif = BIF_HexGet;
		min_params = 2;
		max_params = 3;
	}
	else if (!_tcsicmp(func_name, _T("HexPut")))
	{
		bif = BIF_HexPut;
		min_params = 1;
		max_params = 3;
	}

==================================================

[script2.cpp]

#include "wincrypt.h"
#pragma comment(lib, "Crypt32.lib") //prevent: error LNK2019: unresolved external symbol __imp__CryptStringToBinaryW@28

==================================================

[script2.cpp]

BIF_DECL(BIF_HexGet)
{
	aResultToken.symbol = SYM_STRING;
	aResultToken.marker = _T("");

	bool is_uppercase = 1;
	if (!ParamIndexIsOmitted(2))
	{
		LPTSTR options = ParamIndexToString(2);
		is_uppercase = !StrChrAny(options, _T("Ll"));
	}
	BYTE *address = (BYTE *)ParamIndexToInt64(0);
	DWORD size = (DWORD)ParamIndexToInt64(1);
	DWORD chars = 0;
	bool is_vista_plus = (GetVersion() & 0xFF) >= 6;
	DWORD flags;

	if (is_vista_plus) //if Windows Vista or later
		flags = CRYPT_STRING_NOCRLF|CRYPT_STRING_HEXRAW;
	else
		flags = CRYPT_STRING_HEX; //returns spaces and CRLFs that must be removed
	CryptBinaryToString(address, size, flags, NULL, (DWORD*)&chars);
	TCHAR *hex = new TCHAR[(unsigned int)chars];
	CryptBinaryToString(address, size, flags, hex, (DWORD*)&chars);

	if (is_vista_plus)
	{
		if (is_uppercase)
			CharUpper(hex);
		aResultToken.marker = hex;
		return;
	}

	int j = 0;
	TCHAR *output = new TCHAR[(unsigned int)chars];
	for (int i = 0; i < (int)chars; ++i)
	{
		if (hex[i] != ' ' && hex[i] != '\r' && hex[i] != '\n')
		{
			tmemcpy(&output[j], &hex[i], 1);
			j++;
		}
	}
	if (is_uppercase)
		CharUpper(output);
	aResultToken.marker = output;
}

BIF_DECL(BIF_HexPut)
{
	if (ParamIndexIsOmitted(1))
	{
		if (ParamIndexIsOmitted(2))
		{
			aResultToken.symbol = SYM_INTEGER;
			aResultToken.value_int64 = (__int64)(_tcslen(ParamIndexToString(0))/2);
		}
		else
		{
			aResultToken.symbol = SYM_STRING;
			aResultToken.marker = _T("");
		}
		return;
	}
	TCHAR *hex = (TCHAR *)ParamIndexToString(0);
	BYTE *address = (BYTE *)ParamIndexToInt64(1);
	DWORD chars = 0;
	if (ParamIndexIsOmitted(2))
		chars = (DWORD)_tcslen(ParamIndexToString(0));
	else
		chars = (DWORD)ParamIndexToInt64(2);
	DWORD size = (DWORD)(chars / 2);
	CryptStringToBinary(hex, chars, CRYPT_STRING_HEX, address, (DWORD*)&size, NULL, NULL);
	aResultToken.symbol = SYM_INTEGER;
	aResultToken.value_int64 = (__int64)size;
}

BIF_DECL(BIF_Base64Get)
{
	aResultToken.symbol = SYM_STRING;
	aResultToken.marker = _T("");

	BYTE *address = (BYTE *)ParamIndexToInt64(0);
	DWORD size = (DWORD)ParamIndexToInt64(1);
	DWORD chars = 0;
	bool is_vista_plus = (GetVersion() & 0xFF) >= 6;
	DWORD flags;

	if (is_vista_plus) //if Windows Vista or later
		flags = CRYPT_STRING_NOCRLF|CRYPT_STRING_BASE64;
	else
		flags = CRYPT_STRING_BASE64; //returns CRLFs that must be removed

	CryptBinaryToString(address, size, flags, NULL, (DWORD*)&chars);
	TCHAR *base64 = new TCHAR[(unsigned int)chars];
	CryptBinaryToString(address, size, flags, base64, (DWORD*)&chars);

	if (is_vista_plus)
	{
		aResultToken.marker = base64;
		return;
	}

	int j = 0;
	TCHAR *output = new TCHAR[(unsigned int)chars];
	for (int i = 0; i < (int)chars; ++i)
	{
		if (base64[i] != '\r' && base64[i] != '\n')
		{
			tmemcpy(&output[j], &base64[i], 1);
			j++;
		}
	}
	aResultToken.marker = output;
}

BIF_DECL(BIF_Base64Put)
{
	TCHAR *base64 = (TCHAR *)ParamIndexToString(0);
	DWORD chars = 0;
	if (ParamIndexIsOmitted(2))
		chars = (DWORD)_tcslen(ParamIndexToString(0));
	else
		chars = (DWORD)ParamIndexToInt64(2);
	DWORD size = 0;
	if (ParamIndexIsOmitted(1))
	{
		if (ParamIndexIsOmitted(2))
		{
			CryptStringToBinary(base64, chars, CRYPT_STRING_BASE64, 0, (DWORD*)&size, NULL, NULL);
			aResultToken.symbol = SYM_INTEGER;
			aResultToken.value_int64 = (__int64)size;
		}
		else
		{
			aResultToken.symbol = SYM_STRING;
			aResultToken.marker = _T("");
		}
		return;
	}
	BYTE *address = (BYTE *)ParamIndexToInt64(1);

	CryptStringToBinary(base64, chars, CRYPT_STRING_BASE64, NULL, (DWORD*)&size, NULL, NULL);
	CryptStringToBinary(base64, chars, CRYPT_STRING_BASE64, address, (DWORD*)&size, NULL, NULL);
	aResultToken.symbol = SYM_INTEGER;
	aResultToken.value_int64 = (__int64)size;
}

==================================================
Relevant AHK code:
[Base64Get/Base64Put and HexGet/HexPut]
StrPut/StrGet + hex/base64 - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=50528
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: C++: AHK source code: Base64Get/Base64Put and HexGet/HexPut

Post by jeeswg » 10 Jun 2019, 23:25

I wrote some code to replace spaces/CRs/LFs. Out of interest, are there any existing macros to facilitate this?
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: C++: AHK source code: Base64Get/Base64Put and HexGet/HexPut

Post by Helgef » 06 Jul 2020, 03:32

Disregarding design and usefulness (as BIFs). These functions seems to contain several errors and poor practices. I wouldn't use these as a template.

Post Reply

Return to “C/C++”