c4458 warning - how to find which variable is used - c++

I need to port an old project to the latest visual studio but it has some very awful code in it that I don't know how to resolve.
if have this function:
void CBuffer::AddData( LPBYTE lpData, u_long uDataSize, u_long &uRemnant )
{
int cb;
LPBYTE ptr = GetWritableBuffer( (int *)&cb );
cb = ( cb < uRemnant? cb: uRemnant );
ASSERT( ptr + cb <= m_lpBufMax );
memcpy( (void*)ptr, &lpData[uDataSize - uRemnant], cb );
m_pTail = ptr + cb;
uRemnant -= cb;
}
which prompts
buffer.cpp(90): warning C4458: declaration of 'cb' hides class member
here int cb overwrite u_long cb defined by the class CBuffer.
Is there a way to tell which cb should be used after this?
LPBYTE ptr = GetWritableBuffer( (int *)&cb );

Local variables always shadow class member variables or global variables. So, in this method, always the local variable int cb is used.

Related

A cpp error, an unintialized local Variable 'MemoryInformation'?

class CheckClass {
public:
VOID Bypass() {
DWORD START = (DWORD)GetModuleHandle(NULL);
DWORD OFFSET = START + 0x1000;
MEMORY_BASIC_INFORMATION MemoryInformation;
CCLOCATION = Utility.FindPatternInMemory((unsigned
char*)OFFSET, MemoryInformation.RegionSize + OFFSET, (unsigned
char*)"\xCC\xCC\xCC\xCC", "xxxx");
AddVectoredExceptionHandler(1, CallHandle);
}
};
Basically, MEMORY_BASIC_INFORMATION MemoryInformation, throws an error unintialized local Variable 'MemoryInformation'
How could I fix that? Thanks in advance.

How to look up 64-bit module's function table when it's mapped in memory?

My goal is to understand stack unwinding in 64-bit PE32+ executable format in Windows, or how the following API can calculate addresses of a function prologue, body, epilogue, etc.:
CONTEXT context = {0};
RtlCaptureContext(&context);
DWORD64 ImgBase = 0;
RUNTIME_FUNCTION* pRTFn = RtlLookupFunctionEntry(context.Rip, &ImgBase, NULL);
_tprintf(L"Prologue=0x%p\n", (void*)(ImgBase + pRTFn->BeginAddress));
I know that the information on the offsets of all non-leaf functions used by the linker is included in the PE32+ header in the exceptions directory. So I tried to write my own function to parse it. I got to this point where I got stumped:
//INFO -- must be compiled as x64 only!
void GetFunctionTable(BYTE* lpBaseAddress, size_t szImageSz)
{
if(lpBaseAddress)
{
if(szImageSz > sizeof(IMAGE_DOS_HEADER))
{
IMAGE_DOS_HEADER* pDOSHeader = (IMAGE_DOS_HEADER*)lpBaseAddress;
if(pDOSHeader->e_magic == IMAGE_DOS_SIGNATURE)
{
IMAGE_NT_HEADERS* pNtHeader = (IMAGE_NT_HEADERS*)((BYTE*)pDOSHeader + pDOSHeader->e_lfanew);
PIMAGE_DATA_DIRECTORY pDataDirectories = NULL;
if(pNtHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
{
//64-bit image only
IMAGE_NT_HEADERS64* pHdr64 = (IMAGE_NT_HEADERS64*)pNtHeader;
IMAGE_OPTIONAL_HEADER64* pIOH64 = &pHdr64->OptionalHeader;
pDataDirectories = pIOH64->DataDirectory;
IMAGE_DATA_DIRECTORY* pExceptDir = &pDataDirectories[IMAGE_DIRECTORY_ENTRY_EXCEPTION];
if(pExceptDir->VirtualAddress &&
pExceptDir->Size)
{
IMAGE_RUNTIME_FUNCTION_ENTRY* pRFs = (IMAGE_RUNTIME_FUNCTION_ENTRY*)
GetPtrFromRVA64(pExceptDir->VirtualAddress, pNtHeader, lpBaseAddress);
//'pRFs' = should point to an array of RUNTIME_FUNCTION structs
// but in my case it points to an empty region of memory with all zeros.
}
}
}
}
}
}
with the following helper functions:
PIMAGE_SECTION_HEADER GetEnclosingSectionHeader64(DWORD_PTR rva, PIMAGE_NT_HEADERS64 pNTHeader)
{
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(pNTHeader);
unsigned int i;
for ( i=0; i < pNTHeader->FileHeader.NumberOfSections; i++, section++ )
{
if ( (rva >= section->VirtualAddress) &&
(rva < (section->VirtualAddress + section->Misc.VirtualSize)))
return section;
}
return 0;
}
LPVOID GetPtrFromRVA64(DWORD rva, const void* pNTHeader, const void* imageBase)
{
PIMAGE_SECTION_HEADER pSectionHdr;
INT_PTR delta;
pSectionHdr = GetEnclosingSectionHeader64( rva, (PIMAGE_NT_HEADERS64)pNTHeader );
if ( !pSectionHdr )
return 0;
delta = (INT_PTR)(pSectionHdr->VirtualAddress - pSectionHdr->PointerToRawData);
return (PVOID) ( (BYTE*)imageBase + rva - delta );
}
So I'm testing it on the self executable:
HMODULE hMod = ::GetModuleHandle(NULL);
MODULEINFO mi = {0};
if(::GetModuleInformation(::GetCurrentProcess(), hMod, &mi, sizeof(mi)))
{
GetFunctionTable((BYTE*)hMod, mi.SizeOfImage);
}
But the problem is that inside my GetFunctionTable when I try to look up the function table mapped in memory in the IMAGE_DIRECTORY_ENTRY_EXCEPTION directory, I'm getting a pointer (i.e. IMAGE_RUNTIME_FUNCTION_ENTRY*) to an empty region of memory. I must be not translating the rva address correctly.
So anyone who knows how PE32+ header is mapped in memory, can please show what am I doing wrong there?

Same names in PCBs in array of pointers to Thread

I am writing a code for thread handling in C++. One instance of a Thread has a pointer to PCB structure and in the constructor of the Thread I just call myPCB = new PCB(name, stackSize, timeSlice, this). It was all working just fine until I tried to make an array of pointers to Thread.
When I just make a pointer to thread and initialized it with new Thread(name, stackSize, timeSlice) the name in PCB of that Thread is appointed correctly.
But when I try it with an array of pointers all the PCBs have the same value for name variable.
I have checked and they are all diffrent PCBs (their IDs are diffrent). Their names get properly initialized in the constructor, but somewhere between the end of the constructor of the Nth and the end of the (N+1)th all names get the same value, that of N+1.
PCB constructor:
PCB::PCB(TName namee, StackSize stackSizee, Time timeSlicee,Thread *threadd){
status = begging;
id = genID++;
if(namee) name = namee;
else name = "Thread"+id;
createStack(stackSizee);
thread = threadd;
timeSlice = timeSlicee;
System::numberOfThreads++;
System::allPCBQueue.add(this);
waitingMe = new Queue();
waitingFor = 0;
semaphore = 0;
sleepTime = -1;
}
void PCB::createStack(StackSize stackSize){
intOff;
if(stackSize > maxStack) stack = new char[maxStack];
else stack = new char[stackSize];
newSS = FP_SEG(stack + stackSize);
newSP = FP_OFF(stack + stackSize);
asm{
mov oldSS, ss
mov oldSP, sp
mov ss, newSS
mov sp, newSP
push ax; push bx; push cx; push dx; push es; push ds; push si; push di; push bp
mov newSP, sp
mov newSS, ss
mov sp, oldSP
mov ss, oldSS
}
stackPointer = MK_FP(newSS, newSP);
intOn;
}
I figure its something with createStack() but I don't know what. All help is appreciated.
*Note: I currently don't have constant access to the internet so please don't get angry if I don't reply fastly. I will try to check on this question as much as I can.
EDITED:
PCB class definition:
class PCB
{
static ID genID;
char *stack;
void *stackPointer;
Thread *thread;
TName name;
ID id;
Time timeSlice, sleepTime;
Status status;
Queue *waitingMe;
PCB* waitingFor;
KernelSem* semaphore;
friend class Thread;
// static unsigned newSS, newSP, oldSS, oldSP;
public:
static StackSize maxStack;
PCB(TName name, StackSize stackSize, Time timeSlice,Thread *thread);
~PCB(void);
void runThread();
ID getID(){
return id;
}
TName getName(){
return name;
}
void setStatus(Status status){
this->status = status;
}
Status getStatus(){
return status;
}
int getEnding(){
if(status == ending) return 1;
return 0;
}
int getBegging(){
if(status == begging) return 1;
return 0;
}
void createStack(StackSize stackSize);
void* getStackPointer(){
return stackPointer;
}
void setStack(void *newStackPointer){
stackPointer = newStackPointer;
}
Time getTimeSlice(){return timeSlice;}
Time getSleepTime(){return sleepTime;}
void decrementSleepTime(){sleepTime--;}
void setSemaphore(KernelSem* kersem){this->semaphore = kersem;}
void resetSemphore(){this->semaphore = 0;}
Thread* getThread(){return thread;}
};
Code where this happens:
Producer **pro = new Producer*[N];
for (i=0; i<N; i++){
producerName[8]='0'+i;
pro[i] = new Producer(buff, producerName ,'0'+i, TIME_SLICE);
pro[i]->start();
}
It's the part of a test file that I got with this assignment. It mustn't be changed. But it is regular.
I have put
allPCBQueue->listAll()
after
pro[i] = new Producer(buff, producerName ,'0'+i, TIME_SLICE);
and I always get that all of the names are same. allPCBQueue is a simple list of PCBs
if(namee) name = namee;
else name = "Thread"+id; <<< Doesn't do what you think it does.
"Thread" is a char *, adding a number to it will give you the pointer + offset.
You don't want to SWITCH to your new stack until AFTER you have created it. Instead of using push to store, just use something like this:
stackPointer = MK_FP(newSS, newSP);
unsigned *sp = reinterpret_cast<unsigned *>(stackPointer);
*--sp = 0; // AX
*--sp = 0; // BX
*--sp = 0; // CX
*--sp = 0; // DX
*--sp = default_ds; // You'll have to dig this out with some inline assembler
*--sp = default_es; // You'll have to dig this out with some inline assembler
*--sp = 0; // SI
*--sp = 0; // DI
*--sp = 0; // BP
stackPointer = reinterpret_cast<void *>(sp);
[Of course, it would be easier to just make stackpointer a pointer to int in the first place].
Since the thread is starting from scratch, values of AX, BX, etc, doesn't matter. ES/DS may matter depending on what memory model you are using. Not pushing onto the stack also means you don't have to disable interrupts for this part - always a bonus.
Unfortunately, your code isn't showing what you are doing with "array of PCB's", so I can't say what' wrong there. And I'm sure someone says this should be a comment, not an answer, since it doesn't actually answer your question - but formatting code in comments is nearly hopeless...
Edit:
I'm guessing that "producername" is a local variable in your code that creates the threads. This won't work, but I think it's a bit difficult to dictate that the caller must ensure that the name stays forever, so I think what you should do is:
if(namee)
{
size_t len = strlen(namee);
char *name_buf = new char[len+1];
strcpy(name_buf, namee);
name = name_buf;
}
else
{
// Make up some random name here.
}
The code was
name = namee
or
this->name = namee
I just made it
strcpy(name, namee)
and it works now.

Memory overwritten after allocating array of structs

I'm trying to allocate memory for a array of structures, but after it is allocated a int that is passed in the function is set to '0'... The problem is gone when i increase the size of the array. Here is my code:
wchar_t* ISTFallSensor::JSON_EventLog(int nRecords) {
wchar_t* returnstring = new wchar_t[8192]; memset( returnstring, 0, 8192 * sizeof(TCHAR) );
HINSTANCE hIstDLL;
DWORD (*IST_Open)(TCHAR *, HANDLE *) = 0;
DWORD (*IST_Close)(HANDLE) = 0;
DWORD (*IST_GetMotionEventLogCount)(HANDLE, DWORD, PDWORD) = 0;
DWORD (*IST_GetMotionEventLogRecords)(HANDLE, IST_LOG_RECORD[], int, PINT) = 0;
hIstDLL = LoadLibrary(L"ISTAPI32.dll");
if(hIstDLL && nRecords > 0 ){
IST_Open = (DWORD (__cdecl *)(TCHAR *, HANDLE *))GetProcAddress(hIstDLL, L"IST_Open");
IST_Close = (DWORD (__cdecl *)(HANDLE))GetProcAddress(hIstDLL, L"IST_Close");
IST_GetMotionEventLogCount = (DWORD (__cdecl *)(HANDLE, DWORD, PDWORD))GetProcAddress(hIstDLL, L"IST_GetMotionEventLogCount");
IST_GetMotionEventLogRecords = (DWORD (__cdecl *)(HANDLE, IST_LOG_RECORD[], int, PINT))GetProcAddress(hIstDLL, L"IST_GetMotionEventLogRecords");
HANDLE phIst = INVALID_HANDLE_VALUE;
DWORD openStatus = IST_Open( _T("IST1:"), &phIst );
if ( openStatus == IST_ERROR_SUCCESS ) {
DWORD dropsD; IST_GetMotionEventLogCount(phIst, FREEFALL, &dropsD);
int drops = (int)dropsD;
if ( nRecords > drops ) nRecords = drops; if ( nRecords > 32 ) nRecords = 32;
int pnRecords = 0;
IST_LOG_RECORD eventlog[32] = {0};
DWORD getStatus = IST_GetMotionEventLogRecords(phIst, eventlog, drops, &pnRecords);
The last function gets a list of events and uses the given array to store that info. When the function returns the array is filled correcly, but the nRecords value is overwritten by '0'.
Does anyone know what i am doing wrong here?
You have a memory overflow.
You adjust the variable nRecords so that it won't exceed 32, which is the maximum number of IST_LOG_RECORD that fit the eventlog array.
However you don't use it in the call to IST_GetMotionEventLogRecords. Instead you use drops, which equals to dropsD, which is not limited to 32.
Just use nRecords instead of drops:
DWORD getStatus = IST_GetMotionEventLogRecords(phIst, eventlog, nRecords, &pnRecords);

Template Class Type Sizing

I have written a template class for a circular buffer:
template <class T> class CRingBuffer { /* ... */ };
Some of the operations this class performs rely on an accurate evaluation of the size of T. This seems to work okay when T is BYTE (i.e. sizeof(T) == 1, check). However, when I try to use the same class where T is DWORD, for some reason sizeof(T) evaluates to 16. The last time I checked, a double-word is 4 bytes, not 16. Does anyone know why this is happening? Thanks.
ADDITIONAL INFO
I can't post all the code due to its proprietary nature, but here is the class declaration and the function definition in question:
template <class T> class CRingBuffer
{
#pragma pack( push , 1 ) // align on a 1-byte boundary
typedef struct BUFFER_FLAGS_tag
{
T * pHead; // Points to next buffer location to write
T * pTail; // Points to next buffer location to read
BOOL blFull; // Indicates whether buffer is full.
BOOL blEmpty; // Indicates whether buffer is empty.
BOOL blOverrun; // Indicates buffer overrun.
BOOL blUnderrun; // Indicates buffer underrun.
DWORD dwItemCount; // Buffer item count.
} BUFFER_FLAGS, *LPBUFFER_FLAGS;
#pragma pack( pop ) // end 1-byte boundary alignment
// Private member variable declarations
private:
T * m_pBuffer; // Buffer location in system memory
T * m_pStart; // Buffer start location in system memory
T * m_pEnd; // Buffer end location in system memory
BUFFER_FLAGS m_tFlags; // Buffer flags.
DWORD m_dwCapacity; // The buffer capacity.
// CRingBuffer
public:
CRingBuffer( DWORD items = DEFAULT_BUF_SIZE );
~CRingBuffer();
// Public member function declarations
public:
DWORD Add( T * pItems, DWORD num = 1, LPDWORD pAdded = NULL );
DWORD Peek( T * pBuf, DWORD num = -1, DWORD offset = 0, LPDWORD pWritten = NULL );
DWORD Delete( DWORD num, LPDWORD pDeleted = NULL );
DWORD Remove( T * pBuf, DWORD num = 1, LPDWORD pRemoved = NULL );
void Flush( void );
DWORD GetItemCount( void );
BYTE GetErrorStatus( void );
// Private member function declarations
private:
void IncrementHead( LPBUFFER_FLAGS pFlags = NULL );
void IncrementTail( LPBUFFER_FLAGS pFlags = NULL );
};
template <class T> void CRingBuffer<T>::IncrementHead( LPBUFFER_FLAGS pFlags )
{
ASSERT(this->m_pBuffer != NULL);
ASSERT(this->m_pStart != NULL);
ASSERT(this->m_pEnd != NULL);
ASSERT(this->m_tFlags.pHead != NULL);
ASSERT(this->m_tFlags.pTail != NULL);
pFlags = ( pFlags == NULL ) ? &(this->m_tFlags) : pFlags;
// Verify overrun condition is not set.
if ( pFlags->blOverrun == FALSE )
{
pFlags->pHead += sizeof(T); // increament buffer head pointer
pFlags->blUnderrun = FALSE; // clear underrun condition
// Correct for wrap condition.
if ( pFlags->pHead == this->m_pEnd )
{
pFlags->pHead = this->m_pStart;
}
// Check for overrun.
if ( pFlags->pHead == pFlags->pTail )
{
pFlags->blOverrun = TRUE;
}
}
}
The problem described above occurs when pFlags->pHead += sizeof(T); of IncrementHead is executed.
Oh, this is really simple after all :)
Without realising it, in pFlags->pHead += sizeof(T); you use pointer arithmetic. pHead is a pointer to T, and when you increase it by sizeof(T), it means you move it forward by that many elements of type T, and not by that many bytes as you thought. So the size of T gets squared. If your goal is to move the pointer to the next element of the buffer, you should just increment it by 1: pFlags->pHead += 1;