I have the following code. The code reads a string from a PHP webpage, then converts the code using the MultiByteToWideChar-function. Then it splits the string using the comma-delimiter. It then removes the "xxx=" before the value (for example, "cid={abcd-1234-5678},tid=AAD23HKJD23KVAAAHN23") and attaches the splitted substrings to an array. Then it displays the parameters one by one in a textbox.
I had it working, however I reinstalled my system 2 days ago and since then I cannot seem to get it working again (even though I backed up the working project before reinstalling, which leaves me wondering how this could ever be possible).
So I have been trying for hours and hours and hours the past day, changing every setting in the compiler and project properties I could think of, reinstalling Visual Studio, trying other versions of Visual Studio, installing extra SDK packages... Nothing helped. Then I added some junk code to test whether the wcstok function was even working (it seems that the project died there) and then randomly the entire project worked and the array I talked about before got properly returned. However, if I remove this junkcode or the code after the splitting/returning of the string (which should have no influence on the code above it, leaving me as confused as I could possibly be) it stops working again and seems to die at the "wcstok"-function.
This is my code:
BOOL Commands(LPBYTE command, DWORD size)
{
unsigned int sizeint;
sizeint = (unsigned int)size;
wchar_t params[MAXCHAR];
MultiByteToWideChar(CP_ACP, MB_COMPOSITE, (LPCCH)command, sizeint, (LPWSTR)params, size);
MessageBoxW(0, params, 0, 0);
//wchar_t input[100] = L"A bird came down the walk";
//wchar_t* buffer;
//wchar_t* token = std::wcstok(input, L" ", &buffer);
wchar_t buf2[MAXCHAR], *ptr;
int i;
for (ptr = wcstok(params, L","); ptr != NULL; ptr = wcstok(NULL, L","))
{
CWA(lstrcpyW, kernel32, buf2, ptr);
for (i = 0; i < lstrlenW(buf2); i++)
{
if (buf2[i] == '=' )
{
wchar_t *a[1000];
wcscpy(a[0] + i, buf2 + i + 1);
MessageBoxW(0, a[0] + i, 0, 0);
}
else
{
}
}
}
//HRESULT hr;
//LPCTSTR Url = _T("http://cplusplus.com/img/cpp-logo.png"), File = _T("C:\\Users\\Public\\file.exe");
//////hr = URLDownloadToFile(0, Url, File, 0, 0);
//switch (hr)
//{
// PROCESS_INFORMATION *piinfo; //size = 0x10
// STARTUPINFO *siinfo; //size = 0x44
// CWA(CreateProcessW, kernel32, 0, File, 0, 0, 0, DETACHED_PROCESS, 0, 0, siinfo, piinfo);
//}
CWA(Sleep, kernel32, 100);
return 1;
}
It doesn't work properly when I use the code above, but when I uncomment the junk-code that is commented above, it randomly does work. The first "MessageBoxW" seems to always return the string from the PHP page properly, however once I remove the junkcode, the program gets terminated once the wcstok in the splitting function is reached.
It worked before exactly like this and I am honestly clueless, I hope anyone has an idea what could cause this because it is honestly driving me nuts..
Thanks a lot in advance!
Millie Smith was the one who gave me the place where the code was bugged.
Instead of defining "a" as a wchar_t*, I had to define it as a normal w_char.
So it became "wchar_t a[MAXCHAR]". Then I had to change the "wcscpy(a[0] + i, buf2 + i + 1);" inside the splitting function into "wcscpy(a + i, buf2 + i + 1);".
Learned something new again, undefined behaviour can be a tricky thing.
Thanks for the help and have a nice day!
Related
I have made a tool to parse the IAT out of PEs (IAT hooking also desirable). It works great for almost everything I've tried. There's one process however that I am completely failing to parse; I can iterate through the import descriptors and get the libraries (all with the correct data) but then my code for parsing the functions seems to just produce nonsense or crash. Here is my code:
// hMod is just the process module pointer thingy
LPBYTE pImageBase = (LPBYTE)hMod;
PIMAGE_DOS_HEADER pImgDosHeaders = (PIMAGE_DOS_HEADER)hMod;
PIMAGE_NT_HEADERS pImgNTHeaders = (PIMAGE_NT_HEADERS)((LPBYTE)pImgDosHeaders + pImgDosHeaders->e_lfanew);
PIMAGE_IMPORT_DESCRIPTOR pImgImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((LPBYTE)pImgDosHeaders + pImgNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
if (pImgDosHeaders->e_magic != IMAGE_DOS_SIGNATURE)
// This doesn't happen
LogError("Signature in the PE header wrong!");
for (; pImgImportDesc->Name != 0; pImgImportDesc++) {
libraryName = (LPCSTR)(pImageBase + pImgImportDesc->Name);
// This is all good...
LogDebug("Lib name: %s, RVA: %p", libraryName, pImgImportDesc->Name);
// This is NOT good. pImgImportDesc->OriginalFirstThunk is zero.
if (!pImgImportDesc->OriginalFirstThunk || !pImgImportDesc->FirstThunk) {
LogWarn("Thunk data missing for %s (%d, %d)", libraryName, pImgImportDesc->OriginalFirstThunk, pImgImportDesc->FirstThunk);
}
pOrigThunk = (PIMAGE_THUNK_DATA)(pImageBase + pImgImportDesc->OriginalFirstThunk);
pThunk = (PIMAGE_THUNK_DATA)(pImageBase + pImgImportDesc->FirstThunk);
for (; pOrigThunk->u1.AddressOfData != 0; pOrigThunk++, pThunk++) {
if (pOrigThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) {
LogDebug("Non-string entry at RVA: %p", pOrigThunk->u1.AddressOfData);
}
else {
// here we just get nonsense data. also the wrong number of functions. so we're parsing it all wrong
functionName = (PIMAGE_IMPORT_BY_NAME)(pImageBase + pOrigThunk->u1.AddressOfData);
LogDebug("Function name: %s, RVA: %p", functionName->Name, pOrigThunk->u1.AddressOfData);
// Then we can do something with &pThunk->u1.Function if we so desire
}
}
}
The good folks at NTCore have a 32bit CFF explorer which works well on the process I am trying to read, however that's only from reading the file not the process. I have googled a lot and tried using other people's code but their code is always very similar to the above and also fails (sometimes crashing instead).
Important detail: this code is running injected inside the process, I am not reading a file.
EDIT: It seems I can sort of parse the file itself but this doesn't work in memory, so the real issue is that the IAT is getting obfuscated or something.
Here is the redacted output: https://textsaver.flap.tv/lists/4jsn
(Generated using this code)
Anyone got any suggestions for workarounds or am I at a dead end?
I'm trying to use realloc function in C, to dynamically operate on a char array of strings (char**).
I usually get a realloc():invalid old size error after 41st cicle of the for loop and I really can't understand why.
So, thanks to everyone who will help me ^-^
[EDIT] I'm trying to make the post more clear and following your advices, as a "new active member" of this community, so thank you all!
typedef struct _WordsOfInterest { // this is in an header file containing just
char **saved; // the struct and libraries
int index;
} wordsOfInterest;
int main() {
char *token1, *token2, *save1 = NULL, file[LEN], *temp, *word, **tokenArr;
int n=0, ch,ch2, flag=0, size, init=0,position,currEdit,init2=0,tempEdit,size_arr=LEN,
oldIndex=0,totalIndex=0,*editArr,counterTok=0;
wordsOfInterest toPrint;
char **final;
toPrint.index = 0;
toPrint.saved = malloc(sizeof(char*)*LEN);
editArr = malloc(sizeof(int)*LEN);
tokenArr = malloc(sizeof(char*)*LEN);
final = malloc(sizeof(char*)*1);
// external for loop
for(...) {
tokenArr[counterTok] = token1;
// internal while loop
while(...) {
// some code here surely not involved in the issue
} else {
if(init2 == 0) {
currEdit = config(token1,token2);
toPrint.saved[toPrint.index] = token2;
toPrint.index++;
init2 = 1;
} else {
if((abs((int)strlen(token1)-(int)strlen(token2)))<=currEdit) {
if((tempEdit = config(token1,token2)) == currEdit) {
toPrint.saved[toPrint.index] = token2;
toPrint.index++;
if(toPrint.index == size_arr-1) {
size_arr = size_arr*2;
toPrint.saved = realloc(toPrint.saved, size_arr);
}
} else if((tempEdit = config(token1,token2))<currEdit) {
freeArr(toPrint, size_arr);
toPrint.saved[toPrint.index] = token2;
toPrint.index++;
currEdit = tempEdit;
}
}
}
flag = 0;
word = NULL;
temp = NULL;
freeArr(toPrint, size_arr);
}
}
editArr[counterTok] = currEdit;
init2 = 0;
totalIndex = totalIndex + toPrint.index + 1;
final = realloc(final, (sizeof(char*)*totalIndex));
uniteArr(toPrint, final, oldIndex);
oldIndex = toPrint.index;
freeArr(toPrint,size_arr);
fseek(fp2,0,SEEK_SET);
counterTok++;
}
You start with final uninitialized.
char **final;
change it to:
char **final = NULL;
Even if you are starting with no allocation, it needs a valid value (e.g. NULL) because if you don't initialize a local variable to NULL, it gets garbage, and realloc() will think it is reallocating a valid chunk of memory and will fail into Undefined Behaviour. This is probably your problem, but as you have eliminated a lot of code in between the declaration and the first usage of realloc, whe cannot guess what is happening here.
Anyway, if you have indeed initialized it, I cannot say, as you have hidden part of the code, unlistening the recommendation of How to create a Minimal, Reproducible Example
.
There are several reasons (mostly explained there) to provide a full but m inimal, out of the box, failing code. This allows us to test that code without having to provide (and probably solving, all or part) the neccesary code to make it run. If you only post a concept, you cannot expect from us complete, full running, and tested code, degrading strongly the quality of SO answers.
This means you have work to do before posting, not just eliminating what you think is not worth mentioning.
You need to build a sample that, with minimum code, shows the actual behaviour you see (a nonworking complete program) This means eliminating everything that is not related to the problem.
You need (and this is by far more important) to, before sending the code, to test it at your site, and see that it behaves as you see at home. There are many examples that, when eliminated the unrelated code, don't show the commented behaviour.
...and then, without touching anymore the code, send it as is. Many times we see code that has been touched before sending, and the problem dissapeared.
If we need to build a program, we will probably do it with many other mistakes, but not yours, and this desvirtuates the purpose of this forum.
Finally, sorry for the flame.... but it is necessary to make people read the rules.
I´m trying to make animation by using an address array with an algorithm to calculate the current picture of the animation.
I got two functions, one is a simple "1 to N counter", the other one includes direction, so i can change the direction somewhere and the function therefore starts to only play the animation for that direction.
The image addresses of all direction are saved in an array so that for example 1-3 are up, 4-6 are right, 7-9 are down and 10-12 are left.
Now to my problem:
If i use both my functions the program stops running.
If i only use one function it all works just fine, and since both functions are basically the same just with an other algorithm i don't understand why it stops when i run both functions.
I generate my address array with my own function so i don't need to have tons of rows with:
adr[1] = "bla_1";
adr[2] = "bla_2";
... but it doesn´t work as soon as i use 2 'animation functions'.
I tried to not use the function and write the addresses in by hand, now it works just fine. But that's no possible solution for me.
So i guess i made a mistake inside my address array generating function, even so it works just fine as long as i only use one 'animation function'.
______________________________MAIN_______________________________
char* playerAdr[8];
int count = 0;
char intString[8];
int gvPlayerDir = 2; // just for example!
loadAdrArrPaths( playerAdr, 8, "src/images/player" );
/*
playerAdr[0] = "src/images/player_1.png";
playerAdr[1] = "src/images/player_2.png";
...
playerAdr[7] = "src/images/player_8.png";
*/
printMultiAnimation( playerAdr, 2, 300, setPos(82,50), 1, gvPlayerDir );
//printAnimation( playerAdr, 8, 300, setPos(50,50), 1 );
______________________________HEAD_______________________________
void printAnimation( char* adrArr[], int adrNr, int frameTime, sPos pos, bool transparent ){
int tempInt = ((SDL_GetTicks() - gvTimestamp) / frameTime) % adrNr;
printSurface( adrArr[tempInt], pos, transparent );
}
void printMultiAnimation( char* adrArr[], int adrNr, int frameTime, sPos pos, bool transparent, int dir ){
int tempInt = (((SDL_GetTicks() - gvTimestamp) / frameTime) % adrNr) + ( adrNr * ( dir - 1 ));
printSurface( adrArr[tempInt], pos, transparent );
}
void loadAdrArrPaths( char* adrArr[], int size, char* path ){
int count = 0;
char intString[8];
char tempPath[size][256];
while( count < size ){
sprintf(intString, "%d", count+1);
strcpy( tempPath[count], path );
strcat( tempPath[count], "_" );
strcat( tempPath[count], intString );
strcat( tempPath[count], ".png" );
adrArr[count] = tempPath[count];
//printf("%i - %s\n", count, adrArr[count]);
count++;
}
}
All i want is to use printAnimation and printMultiAnimation together, so that i can have some 'simple animations' and some 'direction based animations' at the same time on my screen.
And like i said, if i declare the images addresses 'by hand' it works just fine so I'm pretty sure i do something wrong in my loadAdrArrPaths -function. Most likely I screwed up with pointers/references?
I hope someone can and will help me.
The problem is in loadAdrArrPaths, in the following line:
adrArr[count] = tempPath[count];
The array tempPath is local to loadAdrArrPaths, so its contents are no longer available after that function returns. The cases where this code works do so by luck. The slightest change can cause the stack to be overwritten, changing the contents of the array.
You can fix it by either having the caller pass the array to loadAdrArrPaths, or by dynamically allocating the storage with malloc.
I have some C code to populate an OCIDate from the epoch time:
In my main program:
OCIDate ocidate;
epoch_to_ocidate(c.f, &ocidate);
And in a library:
void epoch_to_ocidate(double d, OCIDate* ocidate) {
time_t t = (time_t)d;
struct tm *ut = localtime(&t); /* convert to a Unix time */
OCIDateSetDate(ocidate, ut->tm_year + 1900, ut->tm_mon + 1, ut->tm_mday);
OCIDateSetTime(ocidate, ut->tm_hour + 1, ut->tm_min + 1, ut->tm_sec + 1);
}
I am pretty certain this is correct, because I have a check in the calling routine:
#ifdef DEBUG
char* fmt = "DD-MON-YYYY HH24:MI:SS";
ub4 dbufsize=255;
debug("testing converted OCIDate:");
OCIDateToText(h.err, (const OCIDate*)&ocidate, (text*)fmt, (ub1)strlen(fmt), (text*)0, (ub4)0, &dbufsize, (text*)dbuf);
debug(dbuf);
#endif
And I am binding it with:
OCIBindByPos(s, &bh, h.err, (ub4)p, (dvoid*)&ocidate, (sb4)sizeof(ocidate), SQLT_ODT, 0, 0, 0, 0, 0, OCI_DEFAULT);
(dbuf is already defined). And that displays exactly what I would expect. But when it arrives in Oracle it's gibberish, resulting either in a nonsensical date (e.g. 65-JULY-7896 52:69:0 or a either ORA-1858 or ORA-1801). Has anyone seen anything like this before? Thanks!
Solved it - the problem was that ocidate was stack allocated, and binding doesn't copy the value into the bindhandle, it merely sets a pointer, so when it went out of scope, that could have been pointing to anything. So I heap-allocated it instead. Now of course I have to bookkeep it, but I guess that's straightforward enough. Cheers!
I found many examples of CreatingDirectory recursively, but not the one I was looking for.
here is the spec
Given input
\\server\share\aa\bb\cc
c:\aa\bb\cc
USING helper API
CreateDirectory (char * path)
returns true, if successful
else
FALSE
Condition: There should not be any parsing to distinguish if the path is Local or Server share.
Write a routine in C, or C++
I think it's quite easier... here a version that works in every Windows version:
unsigned int pos = 0;
do
{
pos = path.find_first_of("\\/", pos + 1);
CreateDirectory(path.substr(0, pos).c_str(), NULL);
} while (pos != std::string::npos);
Unicode:
pos = path.find_first_of(L"\\/", pos + 1);
Regards,
This might be exactly what you want.
It doesn't try to do any parsing to distinguish if the path is Local or Server share.
bool TryCreateDirectory(char *path){
char *p;
bool b;
if(
!(b=CreateDirectory(path))
&&
!(b=NULL==(p=strrchr(path, '\\')))
){
size_t i;
(p=strncpy((char *)malloc(1+i), path, i=p-path))[i]='\0';
b=TryCreateDirectory(p);
free(p);
b=b?CreateDirectory(path):false;
}
return b;
}
The algorithm is quite simple, just pass the string of higher level directory recursively while creation of current level of directory fails until one success or there is no more higher level. When the inner call returns with succeed, create the current. This method do not parse to determ the local or server it self, it's according to the CreateDirectory.
In WINAPI, CreateDirectory will never allows you to create "c:" or "\" when the path reaches that level, the method soon falls in to calling it self with path="" and this fails, too. It's the reason why Microsoft defines file sharing naming rule like this, for compatibility of DOS path rule and simplify the coding effort.
Totally hackish and insecure and nothing you'd ever actually want to do in production code, but...
Warning: here be code that was typed in a browser:
int createDirectory(const char * path) {
char * buffer = malloc((strlen(path) + 10) * sizeof(char));
sprintf(buffer, "mkdir -p %s", path);
int result = system(buffer);
free(buffer);
return result;
}
How about using MakeSureDirectoryPathExists() ?
Just walk through each directory level in the path starting from the root, attempting to create the next level.
If any of the CreateDirectory calls fail then you can exit early, you're successful if you get to the end of the path without a failure.
This is assuming that calling CreateDirectory on a path that already exists has no ill effects.
The requirement of not parsing the pathname for server names is interesting, as it seems to concede that parsing for / is required.
Perhaps the idea is to avoid building in hackish expressions for potentially complex syntax for hosts and mount points, which can have on some systems elaborate credentials encoded.
If it's homework, I may be giving away the algorithm you are supposed to think up, but it occurs to me that one way to meet those requirements is to start trying by attempting to mkdir the full pathname. If it fails, trim off the last directory and try again, if that fails, trim off another and try again... Eventually you should reach a root directory without needing to understand the server syntax, and then you will need to start adding pathname components back and making the subdirs one by one.
std::pair<bool, unsigned long> CreateDirectory(std::basic_string<_TCHAR> path)
{
_ASSERT(!path.empty());
typedef std::basic_string<_TCHAR> tstring;
tstring::size_type pos = 0;
while ((pos = path.find_first_of(_T("\\/"), pos + 1)) != tstring::npos)
{
::CreateDirectory(path.substr(0, pos + 1).c_str(), nullptr);
}
if ((pos = path.find_first_of(_T("\\/"), path.length() - 1)) == tstring::npos)
{
path.append(_T("\\"));
}
::CreateDirectory(path.c_str(), nullptr);
return std::make_pair(
::GetFileAttributes(path.c_str()) != INVALID_FILE_ATTRIBUTES,
::GetLastError()
);
}
void createFolders(const std::string &s, char delim) {
std::stringstream ss(s);
std::string item;
char combinedName[50]={'\0'};
while (std::getline(ss, item, delim)) {
sprintf(combinedName,"%s%s%c",combinedName,item.c_str(),delim);
cout<<combinedName<<endl;
struct stat st = {0};
if (stat(combinedName,&st)==-1)
{
#if REDHAT
mkdir(combinedName,0777);
#else
CreateDirectory(combinedName,NULL);
#endif
}
}
}