for a program in which I try to create a file and later write into it, I have written the following:
int main(){
...
....
(some code)
....
char DataBuffer[] = "This is the test file";
...
...
}
I get the error "DataBuffer: undeclared identifier" .
I am using Microsoft Visual C++ Express. And in an old asked question here in stackoverflow.com, I have read that Visual C++ uses an old C89 standard and that it does not support C99 standard.
For that reason, I must declare the variables at the beginning(which I did for the rest of the parameters of CreateFile() and WriteFile). I mean, when you consider the following:
DWORD dwCreationDisposition = CREATE_NEW;
Then I split it up and changed it to:
DWORD dwCreationDisposition;
...
dwCreationDisposition = CREATE_NEW
but I do not know how I should do it with an array. So, for example when I write:
char DataBuffer[];
....
DataBuffer[] = = "This is the test file";
Then I also get the same error message.
What can I do ? Is there any possibility to change the compiler options ? Or a chance to rewrite it such that the integrated compiler accepts it as the other splitted variables/parameters ?
best regards,
If you want your string to be re-writable you should so this:
char DataBuffer[MAX_SIZE];
....
strcpy(DataBuffer,"This is the test file");
Also consider using strncpy for avoiding buffer overrun error.
If your string is constant then:
const char DataBuffer[] = "This is the test file";
Related
I have built a libpcre2-8.dll with the help of this Git Repo.
I'm now trying to access the function pcre2_compile from an ABL (Progress) program. (Progress is an old 4GL Language). I'm constantly hitting the error
Could not find the entrypoint _pcre2_compile#40. (3260)
I've already tried many things but it still doesn't work.
The Dynamic Library is 64 bit and Progress is also running in 64 bit.
In ABL (Progress) you can specify the LIBRARY-CALLING-CONVENTION but whether I set it to STDCALL or CDECL or just don't specify it, the error remains the same.
This is a snippet of the Progress ABL I'm trying to execute the function: (code comes from this Git Repo, which works, but only for 32 bit)
PROCEDURE pcre2_compile :
DEFINE INPUT PARAMETER pattern AS CHARACTER. /* const char * */
DEFINE INPUT PARAMETER options AS INTEGER. /* int */
DEFINE OUTPUT PARAMETER errcodeptr AS INTEGER. /* int * */
DEFINE OUTPUT PARAMETER errptr AS MEMPTR. /* const char ** */
DEFINE OUTPUT PARAMETER erroffset AS MEMPTR. /* int * */
DEFINE INPUT PARAMETER tableptr AS INTEGER. /* const unsigned char * */
DEFINE OUTPUT PARAMETER result AS MEMPTR. /* pcre * */
DEFINE VARIABLE libName AS CHARACTER NO-UNDO.
DEFINE VARIABLE hCall AS HANDLE NO-UNDO.
libName = get-library().
CREATE CALL hCall.
ASSIGN
hCall:CALL-NAME = "pcre2_compile"
hCall:LIBRARY = "lib/libpcre2-8.dll"
//hCall:LIBRARY-CALLING-CONVENTION = "STDCALL"
hCall:CALL-TYPE = DLL-CALL-TYPE
hCall:NUM-PARAMETERS = 6
hCall:RETURN-VALUE-DLL-TYPE = "MEMPTR".
hCall:SET-PARAMETER(1, "CHARACTER", "INPUT" , pattern ).
hCall:SET-PARAMETER(2, "LONG" , "INPUT" , options ).
hCall:SET-PARAMETER(3, "HANDLE TO LONG" , "OUTPUT", errcodeptr ).
hCall:SET-PARAMETER(4, "MEMPTR" , "OUTPUT", errptr ).
hCall:SET-PARAMETER(5, "MEMPTR" , "OUTPUT", erroffset ).
hCall:SET-PARAMETER(6, "LONG" , "INPUT" , tableptr ).
hCall:INVOKE().
ASSIGN result = hCall:RETURN-VALUE.
DELETE OBJECT hCall.
END PROCEDURE.
What am I missing?
Update: Checked with Dependency Walker and the functions seem to be visible. They do have a _8 suffix... But even when trying pcre2_compile_8 it still gives me the same error.
I think that you need to change your long integers to INT64.
Is the entrypoint externally visible/accesible?
I've used https://dependencywalker.com/ in the past to figure that out.
Does that change if you specify the ORDINAL option ?
So the problem was that the name of the entry point was "pcre2_compile_8" instead of "pcre2_compile"... Wanted to delete the question because now it looks quite dumb but leaving it anyway...
I have a C app that I need to compile in Windows. And I am really unable to wrap my head around the UNICODE and ANSI concept in Windows
I want to use GetDriveType function and there are 2 variables A and W. There is also a note here saying that GetDriveType is an alias to both and will select either based on some pre-processor.
But how should I call this function ?
This is what I am trying:
const TCHAR* path = "C:\\Users\\";
const TCHAR* trailing_slash = "\\";
size_t requiredSize = mbstowcs(NULL, path, 0);
TCHAR* win_path = (char*)malloc((requiredSize + 2) * sizeof(char));
UINT driveType = 0;
strncpy(win_path, path, requiredSize + 1);
strncat(win_path, trailing_slash, 2);
printf("Checking path: %s\n", win_path);
driveType = GetDriveType(win_path);
wprintf(L"Drive type is: %d\n", driveType);
if (driveType == DRIVE_FIXED)
printf("Success\n");
else
printf("Failure\n");
return 0;
It produces the result
Checking path: C:\Users\
Drive type is: 1
Failure
If I replace GetDriveType with GetDriveTypeA it returns the correct value 3 and succeeds.
I tried another variant too
size_t requiredSize = mbstowcs(NULL, path, 0);
uint32_t drive_type = 0;
const wchar_t *trailing_slash = L"\\";
wchar_t *win_path = (wchar_t*) malloc((requiredSize + 2) * sizeof(wchar_t));
/* Convert char* to wchar* */
size_t converted = mbstowcs(win_path, path, requiredSize+1);
/* Add a trailing backslash */
wcscat(win_path, trailing_slash);
/* Finally, check the path */
drive_type = GetDriveType(win_path);
I see this warning:
'function' : incompatible types - from 'wchar_t *' to 'LPCSTR'
So, which one to use ? How is it generic ? The path I will be reading is from an environment variable on Windows
What is TCHAR and wchar_t etc. ? I found this post, but could not understand much
This Microsoft post says
Depending on your preference, you can call the Unicode functions explicitly, such as SetWindowTextW, or use the macros
So is it Ok to use wchar_t everywhere and call GetDriveTypeW directly ?
Back in the mid-90s you had Windows 95/98/ME that did not support Unicode and NT4/2000/XP that did. You could create source code that could compile with or without Unicode support just by changing the UNICODE define.
This type of code looks like this:
UINT type = GetDriveType(TEXT("c:\\"));
There is no function named GetDriveType, 99% of all functions that take a string parameter in Windows have two versions, in this case GetDriveTypeA and GetDriveTypeW.
Inside the Windows header files you have code that looks like this:
#ifdef UNICODE
#define GetDriveType GetDriveTypeW
#else
#define GetDriveType GetDriveTypeA
#endif
If UNICODE is defined before including windows.h the above code expands to:
UINT type = GetDriveTypeW(L"c:\\");
and if not:
UINT type = GetDriveTypeA("c:\\");
These days most applications should use Unicode. Whether you should use wchar_t/WCHAR and call GetDriveTypeW directly or still rely on the defines is a style question. There might be situations where you need to force the A or W function and that is OK as well.
The same applies to the C library with the _TEXT macro and the _tcs functions except that those are controlled by the _UNICODE define.
If you get a warning about incompatible string types then you are calling the wrong function or you have not added #define UNICODE (and _UNICODE). If you are compiling cross platform code intended for Unix you might have to convert from char* to a wide string in some places.
See also:
TEXT vs. _TEXT vs. _T, and UNICODE vs. _UNICODE
This is my first time using Ghidra and debugging. My project deals with reverse engineering a Dos executable from 2007, to understand how it generates a code.
I looked for the strings I can read when launching the program through wine (debugging under linux) and found one place :
/* Reverses the string */
__strrev(local_8);
local_4 = 0;
DISPLAY_MESSAGE(s__Code_=_%s_0040704c);
with DISPLAY_MESSAGE being :
int __cdecl DISPLAY_MESSAGE(byte *param_1)
{
int iVar1;
int errorCode;
iVar1 = FUN_004019c0((undefined4 *)&DAT_004072e8);
errorCode = FUN_00401ac0((char **)&DAT_004072e8,param_1,(undefined4 *)&stack0x00000008);
FUN_00401a60(iVar1,(int *)&DAT_004072e8);
return errorCode;
}
I named the function "DISPLAY_MESSAGE" because I saw the string on the screen ;-). I would like to name it printf but its signature does not match the one of printf since it takes byte * instead of char *, ... as input parameters and returns an int instead of void for the actual printf.
The string "Code = %s" (stripping the CRs and new lines) is actually located at address "0040704c", and I am very surprised not to see the variable holding the generated code value instead (that could help me rename the variables).
If I change the signature to the one of printf it yields :
DISPLAY_MESSAGE(s__Code_=_%s_0040704c,local_8)
which looks better, because local_8 could be the code, but I don't know if it is correct to change the signature like this (since then the local variable that I renamed errorCode is never used whereas it was returned before signature change).
void __cdecl DISPLAY_MESSAGE(char *param_1,...)
{
int iVar1;
int errorCode;
iVar1 = FUN_004019c0((undefined4 *)&DAT_004072e8);
FUN_00401ac0((char **)&DAT_004072e8,(byte *)param_1,(undefined4 *)&stack0x00000008);
FUN_00401a60(iVar1,(int *)&DAT_004072e8);
return;
}
So my questions are :
Why is Ghidra appending _0040704c to the string (should it help me, and how should I make use of this piece of info) ?
If my signature change is correct, what prevents Ghidra from finding the correct signature from its analysis ?
Should I think there is a problem with the function signature whenever I see undefinedX as it appears in DISPLAY_MESSAGE ?
Any help greatly appreciated!
First, please consider the following piece of code (static function called once from main()):
#define SYSFS_GPIO_DIR "/sys/class/gpio"
#define MAX_BUF ((UI_8)64)
typedef uint8_t UI_8
typedef int32_t SI_32
typedef char CHAR_8
static SI_32 ImuGpioFdOpen(UI_8 gpio)
{
SI_32 fd_gpio_open = -1;
SI_32 byte_count = -1;
CHAR_8 aux_buf[MAX_BUF] = {'\0'};
byte_count = snprintf(aux_buf, sizeof(aux_buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
if((byte_count > 0) && (byte_count < sizeof(aux_buf))){
fd_gpio_open = open(aux_buf, O_RDONLY | O_NONBLOCK );
if(fd_gpio_open < 0){
syslog (LOG_ERR,"gpio/fd_open");
fd_gpio_open = ERROR;
}
}
return fd_gpio_open;
}/*ImuGpioFdOpen*/
On the call to open(), static analysis with Polyspace Code Prover raises and alert regarding MISRA's "Dir 4.1 Run-time failures shall be minimized". The alerts says that: "first argument (file path) may not be a valid string"
We don't seem to understand the directive very well, because all our efforts to solve the alerts like this (we have several similar ones) are not yielding results. I mean, we are clearly not building the string correctly, but since the program compiles and runs correctly, we are at a loss.
What kind of run-time check are we missing?
Thank you!
EDIT: I forgot to mention that passing a string literal seems to work for Polyspace, but it doesn't work if we try to pass string generated at runtime (like in the code). Could it be because open()'s prototype declares that the first argument is const char* and Polyspace is taking it too seriously?
The issue has been judged to be a false positive. The alerts shall be justified accordingly.
Thanks!
I am reading a file say x.c and I have to find for the string "shared". Once the string like that has been found, the following has to be done.
Example:
shared(x,n)
Output has to be
*var = &x;
*var1 = &n;
Pointers can be of any name. Output has to be written to a different file. How to do this?
I'm developing a source to source compiler for concurrent platforms using lex and yacc. This can be a routine written in C or if u can using lex and yacc. Can anyone please help?
Thanks.
If, as you state, the arguments can only be variables and not any kind of other expressions, then there are a couple of simple solutions.
One is to use regular expressions, and do a simple search/replace on the whole file using a pretty simple regular expression.
Another is to simply load the entire source file into memory, search using strstr for "shared(", and use e.g. strtok to get the arguments. Copy everything else verbatim to the destination.
Take advantage of the C preprocessor.
Put this at the top of the file
#define shared(x,n) { *var = &(x); *var1 = &(n); }
and run in through cpp. This will include external resources also and replace all macros, but you can simply remove all #something lines from the code, convert using injected preprocessor rules and then re-add them.
By the way, why not a simple macro set in a header file for the developer to include?
A doubt: where do var and var1 come from?
EDIT: corrected as shown by johnchen902
When it comes to preprocessor, I'll do this:
#define shared(x,n) (*var=&(x),*var1=&(n))
Why I think it's better than esseks's answer?
Suppose this situation:
if( someBool )
shared(x,n);
else { /* something else */ }
In esseks's answer it will becomes to:
if( someBool )
{ *var = &x; *var1 = &n; }; // compile error
else { /* something else */ }
And in my answer it will becomes to:
if( someBool )
(*var=&(x),*var1=&(n)); // good!
else { /* something else */ }