3
votes

I have a dll compiled with /mt. The dll exports a function 'main' which I call from cmd with rundll32. This function will call another one from a header I included which is supposed to take some settings stored in the registry under Environment. To imagine what I am doing ,here's some of the code:

Dll:main

#include "..\Header.h"

extern "C" void APIEXP WINAPI main(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow){
    char *parentPath = nullptr;
    size_t sz;
    DWORD buffSize;
    block;  //this is a messagebox
    buffSize = sizeof(client.pc_name);

    if (!GetComputerNameA(client.pc_name, &buffSize)) strcpy(client.pc_name, "");
    if (!GetUserNameA(client.user_name, &buffSize)) strcpy(client.user_name, "");
    client.os_time = time(0);
    client.version = Version;
    client.os_version = Exe_version;
    TextSetting("pc_description", client.pc_description);
    TextSetting("custom_name", client.custom_name);
}

Header

LPSTR TextSetting(LPSTR setting,LPSTR buff) {
    //Returns all data in buff
    DWORD type, sz;
    msg("dll: ","function called");

    if (RegGetValueA(HKEY_CURRENT_USER,"Environment", setting, RRF_RT_REG_SZ | RRF_RT_REG_MULTI_SZ, &type, (LPBYTE)buff, &sz) != ERROR_SUCCESS) {
        buff[0] = 0;
        msg("sdsv: ", "err");
        return buff;
    }

    return buff;
}
LPSTR con(LPSTR dest, LPSTR a, LPSTR b, LPSTR c) {
    //c is optional and default: ""
    strcpy(dest, a);
    strcat(dest, b);
    strcat(dest, c);

    return dest;
}
VOID msg(LPSTR app,LPSTR a) {
    char temp_buffer[2048];
    con(temp_buffer , app,a, "\n");
    OutputDebugStringA(temp_buffer);
}

The code shown above works perfectly: the point of interest here is the TextSetting in main. It retrieves the data as it should. BUT when I remove the msg("dll: ","function called"); from TextSetting it simply gives an error(the return code is not ERROR_SUCCESS). Moreover I can't even debug the function.When I attach the debugger to rundll32 process the breakpoint I set on the if statement in TextSettings gives the warning mentioned in title.

Here's working: enter image description here

This is weird: enter image description here

Some extra things I noticed: It works if I call msg or con functions(it looks like the str* functions used in con make the code work). Even further: I also works if I only use strcpy and strcat before the if statement. I have no ideea what the problem is(maybe some buffer overflow that miraculously fixes the code used in the if statement?)

1
Here's the idiot question: did you compile under Debug configuration? - AndyG
Release initially but then as debug..no change. Is weird because I knew that under Release the debugger should work. But it does. The project is big and I never changed it before to Debug(only a couple of times). I don't think it affects in any way the behaviour.The screenshots are taken when in Release.. - sergiu reznicencu
Debugging works in Release configurations if you turn off optimizations and generate debugging symbols. The point of a Debug configuration is to have that be easier to do. - AndyG

1 Answers

4
votes

RegGetValue API function expects the last parameter to be the size of the buffer. You are passing an uninitialized variable there. That's probably the reason it has different behaviour between release/debug. RegGetValue