none
Access Violation Writing Location RRS feed

  • Question

  • Hi,

    I am writing a code to identify and display the dll from the registry.

    And my code is..

    #include <windows.h>
    #include <stdio.h>
    #include <tchar.h>
    #include<string>
    #include<iostream>
    #include<vector>
    #include<winerror.h>
    #include <filesystem>
    namespace fs = std::experimental::filesystem;
    //using namespace default;
    #define BUFFER 8192
    #define BUFSIZE 4096
    fs::path dir("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application");
    fs::path full_path;
    #define MAX_KEY_LENGTH 255
    #define MAX_VALUE_NAME 16383
    char path[255];
    void QueryKey(HKEY hKey)
    {
    TCHAR    achKey[MAX_KEY_LENGTH];   // buffer for subkey name
    DWORD    cbName;                   // size of name string 
    TCHAR    achClass[MAX_PATH] = TEXT("");  // buffer for class name 
    DWORD    cchClassName = MAX_PATH;  // size of class string 
    DWORD    cSubKeys = 0;               // number of subkeys 
    DWORD    cbMaxSubKey;              // longest subkey size 
    DWORD    cchMaxClass;              // longest class string 
    DWORD    cValues;              // number of values for key 
    DWORD    cchMaxValue;          // longest value name 
    DWORD    cbMaxValueData;       // longest value data 
    DWORD    cbSecurityDescriptor; // size of security descriptor 
    FILETIME ftLastWriteTime;      // last write time 

    DWORD i, retCode;
    //LONG lResult;
    //TCHAR value[255];
    DWORD BufferSize = BUFFER;

    TCHAR  achValue[MAX_VALUE_NAME];
    DWORD cchValue = MAX_VALUE_NAME;
    //char value[225];


    // Get the class name and the value count. 
    retCode = RegQueryInfoKey(
    hKey,                    // key handle 
    achClass,                // buffer for class name 
    &cchClassName,           // size of class string 
    NULL,                    // reserved 
    &cSubKeys,               // number of subkeys 
    &cbMaxSubKey,            // longest subkey size 
    &cchMaxClass,            // longest class string 
    &cValues,                // number of values for this key 
    &cchMaxValue,            // longest value name 
    &cbMaxValueData,         // longest value data 
    &cbSecurityDescriptor,   // security descriptor 
    &ftLastWriteTime);       // last write time 

    // Enumerate the subkeys, until RegEnumKeyEx fails.

    if (cSubKeys)
    {
    printf("\nNumber of subkeys: %d\n", cSubKeys);

    for (i = 0; i < cSubKeys; i++)
    {
    cbName = MAX_KEY_LENGTH;
    retCode = RegEnumKeyEx(hKey, i, achKey, &cbName, NULL, NULL, NULL, &ftLastWriteTime);
    if (retCode == ERROR_SUCCESS)
    {
    //_tprintf(TEXT("(%d)\t\t %s\n"), i + 1, achKey);
    for (i = 0; i < cSubKeys; i++)
    {
    cbName = MAX_KEY_LENGTH;
    retCode = RegEnumKeyEx(hKey, i, achKey, &cbName, NULL, NULL, NULL, &ftLastWriteTime);

    if (retCode == ERROR_SUCCESS)
    {
    _tprintf(TEXT("\n\n\n\n(%d) %s\n"), i + 1, achKey);

    //concatenating the path

    fs::path file(achKey);
    full_path = dir / file;
    std::cout << full_path << std::endl;

    HKEY hTestKey1;
    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, full_path.c_str(),
    0, KEY_READ, &hTestKey1) == ERROR_SUCCESS)
    {
    QueryKey(hTestKey1);

    }
    RegCloseKey(hTestKey1);
    }
    }
    }
    }
    }
    else
    {
    printf("Number of subkeys:%d\n", cSubKeys);
    printf("Number of Values:%d   %d\n", cValues,cbMaxValueData);
    for (i = 0, retCode = ERROR_SUCCESS; i < cValues; i++)
    {
    cchValue = MAX_VALUE_NAME;
    achValue[0] = '\0';
    retCode = RegEnumValue(hKey, i, achValue, &cchValue, NULL, NULL, NULL, NULL);
    fs::path file1(achValue);
    file1 = full_path / file1;
    char value[255];
    //std::cout << full_path << std::endl;
    std::cout << file1 << std::endl;
    if (retCode == ERROR_SUCCESS)
    {
    _tprintf(TEXT("(%d) %s\t"), i + 1, achValue);

    if (RegGetValue(HKEY_LOCAL_MACHINE,full_path.c_str(), achValue,RRF_RT_REG_EXPAND_SZ,(LPDWORD)REG_EXPAND_SZ , &value, &BufferSize))
    {
    _tprintf(TEXT("%s\n"),value);
    }
    //TCHAR szEnvPath[MAX_PATH];
    //RegQueryValueEx(HKEY_LOCAL_MACHINE, file1.c_str(), NULL,(LPDWORD)RRF_RT_ANY,(LPBYTE) value, &BufferSize);
    /*if (RegQueryValueEx(HKEY_LOCAL_MACHINE, file1.c_str(), NULL, (LPDWORD)RRF_RT_ANY, (LPBYTE)value, &BufferSize)==ERROR_SUCCESS)
    {
    // ExpandEnvironmentStrings((LPCWSTR)value, szEnvPath, MAX_PATH);
    _tprintf(TEXT("%s\n"),value);
    }*/
    }
    }

    }
    // Enumerate the key values. 
    /*if (cValues)
    {
    printf("\nNumber of values: %d\n", cValues);

    for (i = 0, retCode = ERROR_SUCCESS; i < cValues; i++)
    {
    cchValue = MAX_VALUE_NAME;
    achValue[0] = '\0';
    retCode = RegEnumValue(hKey, i, achValue, &cchValue, NULL, NULL, NULL, NULL);
    fs::path file1(achValue);
    full_path = dir / file1;
    char value[255];
    std::cout << full_path << std::endl;
    if (retCode == ERROR_SUCCESS)
    {
    _tprintf(TEXT("(%d) %s\n"), i + 1, achValue);

    if (RegGetValue(HKEY_LOCAL_MACHINE, full_path.c_str(), NULL, RRF_RT_ANY, NULL, &value, &BufferSize))
    {
    //_tprintf(TEXT("%\n"), value);
    //printf("HI");

    }
    }
    }
    }*/
    }


    void __cdecl _tmain(void)
    {
    HKEY hTestKey;
    //HKEY key;
    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, dir.c_str(),
    0, KEY_READ, &hTestKey) == ERROR_SUCCESS)
    {
    QueryKey(hTestKey);
    }
    RegCloseKey(hTestKey);
    }

    During compilation I get a error message stating that "Unhandled exception at 0x74DAA05F (KernelBase.dll) in trail.exe: 0xC0000005: Access violation writing location 0x00000002." Can anyone please resolve it.

    Thursday, August 22, 2019 1:09 PM

All replies

  • During compilation I get a error message stating that "Unhandled exception at 0x74DAA05F (KernelBase.dll) in trail.exe: 0xC0000005: Access violation writing location 0x00000002." Can anyone please resolve it.

    Hello,

    you say "during compilation"? So it should not be a problem in your code, and I don't see where the compiler should through an exception.

    Nevertheless, I was able to compile your code. So my compiler is ok.

    Which compiler/VS do you use, on which system?

    Have you tried to reinstall your VS?

    Regards, Guido

    Thursday, August 22, 2019 1:58 PM
  • During compilation I get a error message stating that "Unhandled exception at 0x74DAA05F (KernelBase.dll) in trail.exe: 0xC0000005: Access violation writing location 0x00000002." Can anyone please resolve it.

    Hello,

    you say "during compilation"? So it should not be a problem in your code, and I don't see where the compiler should through an exception.

    Nevertheless, I was able to compile your code. So my compiler is ok.

    Which compiler/VS do you use, on which system?

    Have you tried to reinstall your VS?

    Regards, Guido

    Just from a quick look it appears that the OP has misspoken.  The access violation occurs in trail.exe.  So it seems to me the problem is in the executing program, not the compilation process.
    Thursday, August 22, 2019 2:07 PM
  • During compilation I get a error message stating that "Unhandled exception at 0x74DAA05F (KernelBase.dll) in trail.exe: 0xC0000005: Access violation writing location 0x00000002." Can anyone please resolve it.

    Just from a quick look it appears that the OP has misspoken.  The access violation occurs in trail.exe.  So it seems to me the problem is in the executing program, not the compilation process.

    Hello OP,

    if you only have misspoken: Where in your code does the exception come? Check the call stack. This could be a NULL-pointer problem, etc.

    Regards, Guido

    Thursday, August 22, 2019 2:14 PM
  • I'm using VS 2017 community. I'm getting this exception when i try to debug the Code. Should I try it by reinstalling the vs again?
    Thursday, August 22, 2019 2:25 PM
  • I'm using VS 2017 community. I'm getting this exception when i try to debug the Code. Should I try it by reinstalling the vs again?

    No.

    What you should do is step through your code line by line in the debugger.  That should enable you to verify that variables contains correct and expected values, parameters passed to Windows API functions are valid and errors are properly handled.  If you do this you should be able to identify the coding errors that are causing the access violation.

    Thursday, August 22, 2019 7:46 PM
  • Visual Studio 2019 pulls up at least one problem with your code. Interestingly, as a spoiler, your real problem is hidden due to you misusing a cast.

    char value[255];
    //std::cout << full_path << std::endl;
    std::cout << file1 << std::endl;
    if (retCode == ERROR_SUCCESS)
    {
    	_tprintf(TEXT("(%d) %s\t"), i + 1, achValue);
    
    	if (RegGetValue(HKEY_LOCAL_MACHINE, full_path.c_str(), achValue, RRF_RT_REG_EXPAND_SZ, (LPDWORD)REG_EXPAND_SZ, &value, &BufferSize))
    	{
    		_tprintf(TEXT("%s\n"), value);
    	}
    }

    The value variable is type char but since you are using the generic macros, RegGetValue and _tprintf will redirect to RegGetValueW and wprintf when the Unicode character set is used. You need to define this as a TCHAR array to get this to work properly. What's worse, the array is 255 bytes, but BufferSize is originally set to 8192 so value is nowhere near large enough to retrieve the largest amount of data that RegGetValue could return. You also never reset BufferSize back to its original value.

    But the clue to figuring this out is the address that it is trying to write to, 0x2. If you substitute the macros for the values in the RegGetValue, there is only one which has this value, REG_EXPAND_SZ and it is the only one which has a cast next to it.

    If you look at the documentation for RegGetValue, pdwType is documented as:

    "A pointer to a variable that receives a code indicating the type of data stored in the specified value."

    Emphasis mine. The receive means that this parameter isn't meant to be used to tell RegGetValue to filter so that it will only get certain types of value, no this is used for RegGetValue to indicate what type the value is. pdwType expects a pointer to a DWORD that tells you what the type of the value is.

    Again this is one of those cases where a cast was used to silence the compiler without fully understanding what was being done. As is always the case with casts, especially reinterpret casts, you really need to stop and ask yourself if this is really what you want to do since you are saying to the compiler, "trust me, I know what I'm doing".


    This is a signature. Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    • Edited by Darran Rowe Thursday, August 22, 2019 9:29 PM
    Thursday, August 22, 2019 9:28 PM
  • I forgot to mention, besides the cast, there is one more problem in the same function call. You take the address of value, which is an array.

    This time the compiler does work against you because this is not something that the compiler will report due to standard conversions. The first thing to remember here is that the type the parameter expects is void * (it is either PVOID or LPVOID but these are just typedefs for void *). The rule that causes problems is that a pointer to anything will silently convert to a typeless pointer (void *). This means that a char * will convert to void pointer or even a char ** will convert to void *.

    The type of an array is type[], but this can degrade to a pointer. So as an example char[] will degrade to char *. This means that passing in value and not taking the address of value is the right answer since it will degrade to char * and then convert to void *.

    The reason why &value also worked is the way the types work. &value has the type of char (*)[], this degrades to char **. This will convert to void * silently.


    This is a signature. Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    Friday, August 23, 2019 1:08 AM