I need to decrypt some data files with wincrypt and examples are few and far between online. The most solid example I've found is here. However, this is using all sorts of types I cannot seem to find information about (CBase64Utils, CString, etc).
I am reading the final solution, trying to understand the process, and have come to this:
// 5. Determine the LENGTH of the BUFFER to hold the corresponding cyphertext.
CBase64Utils bu;
int ipszSourceLen = strlen(pszSource);
char *pszSource2 = bu.Decode(pszSource, &ipszSourceLen);
DWORD dwSourceLen = strlen(pszSource2); // Get the length of the input string.
DWORD dwDataLen = dwSourceLen;
BYTE* pTarget = NULL;
DWORD dwCryptDataLen = dwDataLen;
CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwCryptDataLen, dwDataLen);
This is pure chinese to me. Can anybody make sense of it and hopefully clear some muddy waters? Thanks
The code you linked is horrible. It appears the fellow wrote his encrypt method, and then subsequently wrote his decrypt method simply by copying and pasting the first method and making a few changes (yet leaving a ton of code left over from the encryption process). I wouldn't be surprised if it works, it's just that it wastes time and space doing useless work left over from encryption (plus the comments are all backwards).
As wincrypt is a Microsoft library, there are plenty of examples over at the MSDN. As MSDN samples are (usually) well-written and well-commented, they should be much easier to understand, so I would recommend you look at them instead.
Related
To anyone that can help Please,
(My operating system is Windows XP)
I have looked on the this forum but have not found a similair answer that I could use or adapt to suite this particular situation. I will try to explain (I apologise in advance if my question seems confusing)
I am constructing a batch file that will call a C++ program (.exe) The C++ program is hard coded to the C: drive. By the way I did not write the C++ program as I am incapable of writing in C++ but would like to exchange the C: in C++ for what would be in batch %SystemDrive%. The line of code in C++ reads as follows:
SetSfcFileException(0, L"c:\\windows\\system32\\calc.exe",-1);
// Now we can modify the system file in a complete stealth.
}
The bit of code I would like to alter in the above code is C: or "C" to change it to %systemDrive% but in C++ code language, in effect change the hard coded part of the C++ program to read a System path variable within XP.
I have also looked elsewhere on the net but have not found a suitable answer as I do Not want to break the C++ code you see.
The C++ code was obtained from the folowing website written by Abdellatif_El_Khlifi:
https://www.codeproject.com/Articles/14933/A-simple-way-to-hack-Windows-File-Protection-WFP-u
Many Thanks for any help given,
David
The search term you should be looking for is Known Folders.
Specifically, calling SHGetKnownFolderPath() with the FOLDERID_System identifier, one of the many IDs found here.
That's for Vista or better. For earlier than that (such as XP), you have to use CSIDL values, CSIDL_SYSTEM (see here for list) passed into SHGetFolderPath().
You can still use the pre-Vista ones but I think they're just thin wrappers around the newer ones.
This is the simplest console application I could come up with that shows this in action (Visual Studio 2019):
#include <iostream>
#include <shlobj_core.h>
#include <comutil.h>
int main()
{
PWSTR path = NULL;
HRESULT hr = SHGetKnownFolderPath(FOLDERID_System, 0, NULL, &path);
_bstr_t bstrPath(path);
std::string strPath((char*)bstrPath);
std::cout << "Path is '" << strPath << "'\n";
}
and the output on my system is:
Path is 'C:\WINDOWS\system32'
This is not really answering my own question, well it is but in a alternative manner, many ways to skin a cat so to speak!
Here is one encouraging bit of news though I have stumbled across the very thing I need called WFPReplacer, it is a commandline windows utility that pretty well does what I want & generally in the same manner. it disables WFP for both singular files & can be used for wholesale switching off of WFP if the right file is replaced. All I need to do is write a batch file as a front end to back up the system files I want to disable use WFPReplacer.exe. So if in the event of the proceedings the routine gets stuffed I can revert back to the backed up files. I think this program uses the same type of embedded coding but is written in Delphi/pascal, it is called Remko Weijnen's Blog (Remko's Blog) "replacing Wfp protected files".
I generally like to leave whatever I am doing on a positive note. So just in case someone else lands on this forum & is trying to accomplish a similair exercise here is the code that one can compile (This is not my code it belongs to Remko Weijnen's Blog (Remko's Blog)) Please be advised it is NOT C++ it is a commandline exe Delhi/Pascal found at this link, so all credits belong to him. The link is:
https://www.remkoweijnen.nl/blog/2012/12/05/replacing-wfp-protected-files/
DWORD __stdcall SfcFileException(RPC_BINDING_HANDLE hServer, LPCWSTR lpSrc, int Unknown)
{
RPC_BINDING_HANDLE hServerVar; // eax#2
int nts; // eax#6
__int32 dwResult; // eax#7
DWORD dwResultVar; // esi#9
int v8; // [sp+8h] [bp-8h]#1
int v9; // [sp+Ch] [bp-4h]#1
LOWORD(v8) = 0;
*(int *)((char *)&v8 + 2) = 0;
HIWORD(v9) = 0;
if ( !hServer )
{
hServerVar = _pRpcHandle;
if ( !_pRpcHandle )
{
hServerVar = SfcConnectToServer(0);
_pRpcHandle = hServerVar;
if ( !hServerVar )
return 0x6BA; // RPC_S_SERVER_UNAVAILABLE
}
hServer = hServerVar;
}
nts = SfcRedirectPath(lpSrc, (int)&v8);
if ( nts >= 0 )
dwResult = SfcCli_FileException((int)hServer, v9, Unknown).Simple;
else
dwResult = RtlNtStatusToDosError(nts);
dwResultVar = dwResult;
MemFree(v9);
return dwResultVar;
}
Also as one further warning (Unless you know what you are doing!!!) do not attempt to use this program, ALWAYS ALWAYS ALWAYS backup your system files before deletion or alteration.
What this program will do is disarm WFP for 60 seconds whilst you intercange or amend your files. Example usage for example is:
WfpReplacer.exe c:\windows\Notepad.exe (Errorlevel true or false will be produced on execution).
Best Regards
David
I have my protobuf-message set up fine it seems, all other fields I have transmit correctly across the network and do not truncate. I only have one problem, when I read the binary data of a picture or file then send it through google protobuf as bytes array type, on the other side it only contains the first 4 elements of the array. If the picture is say 200kb, on the other end it comes out as 1kb(Basically only contains a header or identifier). This problem is kinda complex so I will try to give a run down. Sorry if I make this impossible to understand. I may be going about this completely the wrong way.
Example below contains conceptual work, and was written in class. It very well could contain small errors. The code compiles at home, and if it is a typo let me know and I can fix it.
FILE* file;
FILE* ofile;
file = fopen("red.png", "rb");
fseek(file, 0, SEEK_END);
long fSize = ftell(file);
rewind(file);
BYTE* ret = new BYTE[fSize];
fread(ret, 1, fSize, file);
fclose(file);
char dataStream[1024] //yes it is large enough
myPacket.set_file(ret);
//set other fields here
myPacket.SerializeToArray(dataStream,sizeof(dataStream));
//send through sockets below, works for all but file field.
I can include more when I get back home to my main work computer, sorry, was just hoping I could let this stew while at class. If this is not enough info feel free to give me the smack down, it's alright just looking for advice. I also know that certain image formats can be read certain ways, but I was able to copy a png and rewrite it through binary locally, just not over protobuf
Thanks for reading my pseudo book guys, I am finally trying to leap into improving my knowledge.
Edited quickly typed pointer error(&ret) to (ret). Also then should size of be sizeof(myPacket) rather.
You have written this:
char dataStream[1024] //yes it is large enough
But how could 1024 bytes buffer be large enough if you want to store 200 000 bytes into it?
Better allocate a bigger buffer on the heap, e.g.:
std::vector<char> dataStream(500000);
myPacket.SerializeToArray(&dataStream[0], dataStream.size());
I'm having a lot of difficulty understanding and implementing the Windows Crypto API to Import and Export Keys in c++.
Despite reading through the MSDN documentation many many times I can't seem to get it to work in the way I want.
Below is a snippet of code from what i'm working on.
if(CryptAcquireContext(&CryptoHandle,NULL,provPointer, PROV_RSA_AES, 0xF0000000))
{
HCRYPTKEY aesKey;
//We now have context on Enhanced AES
if(CryptGenKey(CryptoHandle,CALG_AES_128,CRYPT_EXPORTABLE,&aesKey))
{
DWORD dwBlobLen;
BYTE* pbKeyBlob;
CryptExportKey(aesKey,0,PLAINTEXTKEYBLOB,0,NULL,&dwBlobLen);
if(pbKeyBlob=new BYTE[dwBlobLen])
{
if(CryptExportKey(aesKey, NULL,PLAINTEXTKEYBLOB, 0,pbKeyBlob, &dwBlobLen))
{
//Blah Blah
}
}
}
}
*(Where provPointer is a pointer to the Enhanced crypto api string.
As you might be able to tell from the snippet i'm trying to export a AES 128 key to plaintext.
In the debugger it all executes fine (No visible errors) but I don't understand the outcome at all.
The first call to CryptExportKey fills the dwBlobLen with '28' (What does this mean? Why?)
After the second CryptExport key i've tried writing pbKeyBlob(Which I assume points to the key) to file But I just end up with a constant set of bytes (Same for every try) followed by a set of bytes that I different every time (I assume this is some of the key) (Which add to 28 bytes total)
I'd really appreciate if someone could identify where I've gone wrong. I'm pretty clueless with the whole crypto lingo (Sessions,machine keys, blobs etc.)
In the future I'd like to be able to generate an AES key, use it and export it into a file in a form where I can import it again later.
Thanks in advance.
I'm not an expert on the Windows Cryptography API (or on cryptography in general) but I believe I can shed some light on what's going on here.
The first call to CryptExportKey puts 28 in dwBlobLen because that is the size of the blob that it will created when the key is exported. This is in the MSDN docs: http://msdn.microsoft.com/en-us/library/windows/desktop/aa379931%28v=vs.85%29.aspx
AS far as what you're doing wrong. You aren't doing anything wrong. You are asking CryptExportKey to export a plaintext blob which has the following layout:typedef struct _PLAINTEXTKEYBLOB {
BLOBHEADER hdr;
DWORD dwKeySize;
BYTE rgbKeyData[];
} PLAINTEXTKEYBLOB, *PPLAINTEXTKEYBLOB;
As you can see, the blob starts with a header and a key size (which is the constant set of bytes which you have reported, and should be 12 bytes long), followed by the key data (which is the data that changes every time, and should be 16 bytes long). Remember you are generating a 128 bit key (which is 16 bytes).
The BLOBHEADER has the following layout:typedef struct _BLOBHEADER {
BYTE bType;
BYTE bVersion;
WORD Reserved;
ALG_ID aiKeyAlg;
} BLOBHEADER;
By the way, from the doc on the CryptImportKey function, you can't import the PLAINTEXTBLOB directly, because the BYTE array that you pass to CryptImportKey does not include the keysize. You need to pass a buffer with the BLOBHEADER followed by the key data.
This MSDN article is supposed to demonstrate how to delete a registry key which has subkeys, but the code is flawed.
The line that says
StringCchCopy (lpEnd, MAX_PATH*2, szName);
causes an exception, which is due to trying to copy to beyond the buffer of lpEnd. I tried correcting the solution by replacing that line with the following
size_t subKeyLen = lstrlen(lpSubKey);
size_t bufLen = subKeyLen + lstrlen(szName)+1;
LPTSTR buf = new WCHAR[bufLen];
StringCchCopy(buf,bufLen,lpSubKey);
StringCchCopy(buf+subKeyLen,lstrlen(szName)+1,szName);
buf[bufLen-1]='\0';
I'm unable to step through the code as the target platform and dev platform are different, but from the logging I've put in the code it looks like it just freezes up, but doesn't throw an exception.
It's frustrating that MSDN articles are wrong...you'd think they would be checked.
Any ideas on how to correct this?
Thanks.
If you don't mind having Shlwapi.dll as an additional dependency, it may be easier for you just to use SHDeleteKey. If you're only targetting Vista+, RegDeleteTree (which lives in Advapi32.dll) is another alternative.
That change by itself would not be sufficient. The line of code following it:
if (!RegDelnodeRecurse(hKeyRoot, lpSubKey)) {
break;
would also need to change. lpSubKey would need to be replaced with buf since that now contains the full key.
And it probably goes without saying, but be sure to free (delete) buf as part of the cleanup.
However, for correctness, it seems as if it would be better just to fix the original line of code by changing it to pass the correct length (which should be okay since I believe the maximum key length in the registry is 255):
StringCchCopy (lpEnd, MAX_PATH*2 - lstrlen(lpSubKey), szName);
I am trying to delete a resource bitmap through code and am having trouble doing it. Went through several hours of headbanging with google. Here is the code:
int result;
HANDLE h;
h = BeginUpdateResource(L"C:\\Users\\Steve\\Desktop\\stub.exe", FALSE);
result = UpdateResource(h, RT_BITMAP, MAKEINTRESOURCE(IDB_BITMAP2), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), NULL, 0);
EndUpdateResource(h, FALSE);
When I debug, variable "result" ends up being NULL which means that the update didn't go through. Is there something incredibly basic that I'm missing?
Ok, I figured out what went wrong. First off, I used the "GetLastError()" command to help widdle down the possibilities. It gave me an error 0x57 which means ERROR_INVALID_PARAMETER.
When I experimented more, it seems that in the language paramters, I listed "MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)" instead of "MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)". Apparently, resources care about the language you are using even if it's something like a bitmap which doesn't use language.
Once I put in LANG_ENGLISH paramters, it worked. You can find out what language you are using by inspecting the text of the .rc that the resource is using to build.,