I have encountered a problem in my program that has me somewhat stumped. I had a program that was working fine (it was working fine on VS 2010 this is not an I upgraded to .NET and this error started happening post) with a program that is mostly c and some c++ (my boss HATES object oriented since it usually involves making calls to libraries that he is paranoid microsoft will stop supporting and would also have to be delivered to the customer if they have an older version which could be a problem since a lot of them are government and he also thinks that these calls cause unnecessary overhead so I have to try to avoid it as much as possible) then I uncommented a block of code (I will post this block a little lower as it has been modified some from the original one I uncomented) to start working on it and got the error "Runtime check error #2 the stack around "std" has been corrupted" where std is a c style string of wchar.
I tried to figure out what the problem was by implementing some of the not so good fixes since if one works I will know what the actual problem is and then have a good base starting point for debugging. First I tried to increase the size of std to make it large enough that I wouldn't be putting a string larger than it can handle in it (it's values come from no more than 3 columns from a list view each of which can't be bigger than 80 characters) and even though this made me get the error less often I still got it.
So I tried switching std in that block of code to msg (which was exactly the same as std at the time) to see if msg got the same error (which would mean it was produced by that block of code) but the error still came up around std.
case IDC_TXT:
//FileSaveBox(hwnd, L"Save as...",L"Text Files (*.txt)\0*.txt\0All Files\0*.*\0",L"*.txt",wFileName);
FileSaveBox(hwnd, L"Save as...",L"CSV (Coma delimited) (*.csv)\0*.csv\0All Files\0*.*\0",L"*.csv",wFileName);
if(wcslen(wFileName)==0) return 0;
fin.open(wFileName);
if(fin.is_open())
val=MessageBox(hwnd,L"This file allready exists. Do you want to overwrite it?",L"Confirm Save", MB_YESNO);
fin.close();
if (val == IDNO)
return 0;
fout.open(wFileName);
if(!fout.is_open()) return 0;
/*if ((fp = _wfopen (wFileName, L"w"))==NULL)
{
Message("Cannot Open File");
return 0;
}*/
_swprintf(msg,L"Some string");
if(im.col3)
wcscat(msg,L", another string");
fout << msg << L"\n";
count = ListView_GetItemCount(hlvim);
for(i=0;i<count;i++)
{
ListView_GetItemText(hlvim,i,0,msg,240);
wcscat(msg,L", ");
ListView_GetItemText(hlvim,i,1,temp,80);
wcscat(msg,temp);
if(im.col3)
{
wcscat(msg,L", ");
ListView_GetItemText(hlvim,i,2,temp,80);
wcscat(msg,temp);
}
fout << msg << L"\n";
//fprintf(fp,"%s\n",msg);
}
//fclose(fp);
fout.close();
SetFocus(hwnd);
return 0;
This made me think that maybe it was just some other variable writing over the canary around std so I commented it out after replacing all instances of it with msg (execpt for the ones where it is a local variable to a function that hasn't gotten called yet when the error occurs) but this just caused the error to appear around msg (which actually also shows up as a local variable to a function).
Next I tried declaring msg on the heap instead of the stack by using static (since using new would involve my bosses so hated modern code) but this only cased the following error to occur: "Unhandled exception at 0x00300030 in HTZx86.exe: 0xC0000005: Access violation reading location 0x00300030." and at location 0x00300030 is a call to an external API which I have no control over.
Now after I have made some unrelated modifications to other parts of my code I randomly get the stack arror around std and msg at the same time (sometimes after the function call and sometimes before) and not on a consistent basis ether. I would like to know if there is any good way to debugged this problem since break points alone aren't helping me and neither is the call stack (although I may be using them wrong)?
Bellow are the declarations of the variables and the only other place where it would be called before the function gets called:
Declarations:
int i,j,k,count,val,ntx,nrx,IsActive, rxcount;
BOOL callsign, map2rx, rxhit;
double f1,f2,f3;
WCHAR str[80];
static WCHAR msg[240];
WCHAR temp[80];
static short dir;
//FILE* fp;
std::wofstream fout;
std::wifstream fin;
LV_COLUMN pcol;
LV_ITEM pit, pit2;
static HWND hlvtx;
static HWND hlvrx;
static HWND hlvim;
and other calls:
count = ExternalAPIFunction2t();
for(i=0;i<count;i++)
{
ntx = _wtoi(ExternalAPIFunction1(i+1,_SP_NBTXCH));
nrx = _wtoi(ExternalAPIFunction1(i+1,_SP_NBRXCH));
IsActive = _wtoi(ExternalAPIFunction1(i+1,_SP_ISACTIVE));
try
{
for(j=0;j<ntx && IsActive;j++)
{
f1 = _wtof(ExternalAPIFunction1(i+1,_SP_TXCH01+j));
_swprintf(msg,L"%09.4f MHz",f1);
pit.mask = LVIF_TEXT|LVIF_PARAM;
pit.iItem = j;
pit.iSubItem = 0;
pit.lParam = j;
wcscpy_s(msg,ExternalAPIFunction1(i+1,_SP_CALLSIGN));
wcscat_s(msg,L"_CH");
_itow(j+1,temp,80);
wcscat_s(msg,temp);
pit.pszText = msg;
ListView_InsertItem(hlvtx,&pit);
_swprintf(msg,L"%.4f",f1);
pit.mask = LVIF_TEXT;
pit.iSubItem = 1;
pit.pszText = msg;
ListView_SetItem(hlvtx,&pit);
f1 = _wtof(ExternalAPIFunction1(i+1,_SP_NOMINALPOWER));
_swprintf(msg,L"%.1f",f1);
pit.iSubItem = 2;
pit.pszText = msg;
ListView_SetItem(hlvtx,&pit);
_swprintf(msg,L"%f",i+1);
pit.iSubItem = 3;
pit.pszText = msg;
ListView_SetItem(hlvtx,&pit);
}
}catch(std::exception &e)
{
MessageBox(hwnd,(wchar_t*) e.what(),L"Error", MB_OK);
}
for(j=0;j<nrx && IsActive;j++)
{
f1 = _wtof(ExternalAPIFunction1(i+1,_SP_RXCH01+j));
pit.mask = LVIF_TEXT|LVIF_PARAM;
pit.iItem = j;
pit.iSubItem = 0;
pit.lParam = j;
wcscpy(msg,ExternalAPIFunction1(i+1,_SP_CALLSIGN));
wcscat(msg,L"_CH");
_itow(j+1,temp,10);
wcscat(msg,temp);
pit.pszText = msg;
ListView_InsertItem(hlvrx,&pit);
_swprintf(msg,L"%.4f",f1);
pit.mask = LVIF_TEXT;
pit.iSubItem = 1;
pit.pszText = msg;
ListView_SetItem(hlvrx,&pit);
f1 = _wtof(ExternalAPIFunction1(i+1,_SP_RXBANDWIDTH));
_swprintf(msg,L"%.2f",f1);
pit.iSubItem = 2;
pit.pszText = msg;
ListView_SetItem(hlvrx,&pit);
_swprintf(msg,L"%f",i+1);
pit.iSubItem = 3;
pit.pszText = msg;
ListView_SetItem(hlvrx,&pit);
}
}
P.S. ExternalAPIFunction1 was the one with the access violation.
The code is littered with time bombs. That starts with FileSaveBox where you pass a string buffer but don't tell the function how long the buffer is. Add copious amounts of _swprintf, wcscpy and wcscat calls, none of which checks if the buffer may overrun and the RTC error is easily explained.
You know how to use wcspcy_s and wcscat_s, make it consistent.
Related
I am curious to know if it is possible to extend a process module, like a dll, to be larger.
As an example, I inject test.dll into test.exe, I make test.dll + 0x1000 bytes larger, these new bytes now have PAGE_EXECUTE privileges and I can modify them however I like.
I want to be able to do this only after injecting the dll, not by adding fake code to the dll to overwrite, as I will likely have no control over the execution of the actual test subject.
I have already tried to use VirtualAlloc on the end of the dll's sections to increase its size, but it hasn't worked, I usually get ERROR_BAD_ADDRESS, I made sure to verify the process had enough space after the dll to allocate to and commit to.
uint64_t module_contents = (uint64_t)GetModuleHandleA(NULL);
IMAGE_DOS_HEADER* dos_header = (IMAGE_DOS_HEADER*)module_contents;
IMAGE_NT_HEADERS64* nt_header = (IMAGE_NT_HEADERS*)(module_contents + dos_header->e_lfanew);
IMAGE_SECTION_HEADER* section = (IMAGE_SECTION_HEADER*)(nt_header + 1);
for (unsigned short i = 0; i < nt_header->FileHeader.NumberOfSections; i++) {
if (!section->SizeOfRawData && section->Characteristics & IMAGE_SCN_MEM_EXECUTE) {
char name[8];
memcpy(name, section->Name, sizeof(name));
if (std::string(name).find("text") == std::string::npos) {
//std::cout << name << std::endl;
break;
}
}
section++;
}
std::cout << VirtualAlloc((void*)(module_contents + section->VirtualAddress + section->Misc.PhysicalAddress), 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE) << std::endl;
The expected result of this is to fill in and commit to the empty space after the module's sections, which I verify has not been committed to both by the cout & with Cheat Engine to look at the memory region. The result I get is an error message of 0x1E7, or ERROR_INVALID_ADDRESS. I have gotten other error messages like ERROR_INVALID_PARAMETER, when using a smaller size like 0x1.
Any help with this is appreciated!
I am attempting to simply test for the presence of a Smart Card in Windows. The goal is to have a "daemon" running that will perform an action whenever (and for the duration) a card is inserted.
I have zero experience with things of this nature. I have read the documentation for SCardStatus and such, but I don't understand how the whole API works so I'm a bit lost.
What would be most helpful for me is if someone has a very simple example of a complete program that simply tests for the presence of a card (preferably in C++ but I'll take what I can get!). I would be most appreciative. I don't need any card status other than it exists. Thanks!
if you work on windows you need to use WinSCard API, if you use unix, then use PCSC. These two APIs are very similar, because of standards, but WinSCard API is much bigger and gives much more functions to use. These two APIs are implemented with C language, but you can wrap them in C++ pretty easy. I just whant to point out if you gonna wrap those two APIs in to C++ to use it ever on windows AND on unix take a look at smart card protocols numerical values, those are different on these platforms.
Basics:
You need to establish context (its like creating smart card manager)
SCardEstablishContext
It takes 4 parameters but, for basic using, you need only 2, scope and pointer to context handle.
LPSCARDCONTEXT hSCardContext = NULL;
int ret = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &hSCardContext);
if (ret != ERROR_SUCCES) ... // handle error
Smart card are grouped in different groups. So there is functions to work with groups, to create it and so on.
To get readers list (for basic applications you actually dont really need groups)
SCardListReaders
It takes 4 parameters, context, pointer to group, pointer to readers and pointer to reader count
you can use it lise this
char *szGroups = NULL;
long readers = 0;
int res = SCardListReaders(hSCardContext, szGroups, NULL, &readers);
// handle errors
you get readers count first. now you can allocate memory for actual readers.
szReaders = (char *) malloc(sizeof(char) * readers);
int res = SCardListReaders(hSCardContext, szGroups, szReaders , &readers);
Now you have list of readers connected.
You can connect to a reader like so
LPSCARDHANDLE hSCard = NULL;
long activeProtocols = 0;
int ret = SCardConnect(hSCardContext, myReader, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_TX, &hSCard, &activeProtocols);
// .. handle errors
specify protocols, share mode, use SCARD_SHARE_EXCLUSIVE for share mode if youre working with sensitive stuff witch needs protection that OS wont interact with transactions.
Once again if you are wrapping for windows and unix ( unix does not have SCARD_PROTOCOL_TX protocol) but it is a representation of these two SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1.
myReader is the name of connected reader. Like (LPCTSTR)"Dermalog LF10"
you get those reader names from SCardListReaders function.
now you are connected with a card. with SCARD_SHARE_EXCLUSIVE sharing dont forget to release the smart card context, because it will deadlock.
use SCardDisconnect to disconnect, it takes 2 parameters, SmartCard handle, and disposition, for basic application SCARD_LEAVE_CARD disposition should be ok. It specifies that you dont want to do anything special to the card, you dont want to eject or whatever.
Transactions are more complex, because you need to know SCard standards and what not. But i covered the basics.
Keep in mind that this code might not compile, you need to improve types, for windows you need to cast those types in WinAPI types, like LPCTSTR, that it wont complain and unix dont have such types so you need to work around these problems too.
This sample code assumes card readers are plugged in at the start, it does not handle a changing number of card readers.
Other than that, it simply spams the console with inserted / not inserted status of cards.
Please do not use this as-is in production code, most error checking is omitted and some shortcuts are taken to keep the code short(ish).
#pragma comment(lib, "winscard.lib")
#include <vector>
bool test()
{
DWORD dwReaders;
LPSTR szReaders = NULL;
SCARDCONTEXT hContext;
bool bRunning = true;
std::vector<const char*> cards;
LONG status = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &hContext);
if( status != SCARD_S_SUCCESS ) {
return false;
}
dwReaders = SCARD_AUTOALLOCATE;
if( SCardListReadersA(hContext, NULL, (LPSTR)&szReaders, &dwReaders) == SCARD_S_SUCCESS ) {
LPSTR reader = szReaders;
while (reader != NULL && *reader != '\0') {
std::cout << "Reader name: '" << reader << "'" << std::endl;
cards.push_back( reader );
reader += strlen(reader)+1;
}
LPSCARD_READERSTATEA lpState = new SCARD_READERSTATEA[cards.size()];
for( size_t n = 0; n < cards.size(); ++n ) {
memset( lpState + n, 0, sizeof(SCARD_READERSTATEA) );
lpState[n].szReader = cards[n];
}
do {
status = SCardGetStatusChangeA( hContext, 500, lpState, cards.size() );
switch( status )
{
case SCARD_S_SUCCESS:
case SCARD_E_TIMEOUT:
for( size_t n = 0; n < cards.size(); ++n ) {
if( lpState[n].dwEventState & SCARD_STATE_PRESENT) {
std::cout << "'" << lpState[n].szReader << "' present" << std::endl;
} else {
std::cout << "'" << lpState[n].szReader << "' not present" << std::endl;
}
}
break;
default:
std::cout << "Other result: " << status << std::endl;
break;
}
Sleep( 1000 ); // do not spam too bad
} while( bRunning );
// only do this after being done with the strings, or handle the names another way!
SCardFreeMemory( hContext, szReaders );
}
SCardReleaseContext( hContext );
return true;
}
I wonder why this code doesn't work:
#include <iostream>
using namespace std;
int main()
{
int *pointer = (int*)0x02F70BCC;
cout<<*pointer;
return 0;
}
In my opinion it should write on the screen value of 0x02F70BCC,
instead of this my programm crashes.
I know that memory with adress 0x02F70BCC stores value of 20.
But like I said no matter what it just doesn't want to show correct number.
Please help me guys, detailed explanation would be very nice of you.
It doesn't work, because you won't get access to every location in memory you want. Not every location in memory is valid, you may want to read about Virtual Address Space.
Some addresses are reserved for device drivers and kernel mode operations. Another range of addresses (for example 0xCCCCCCCC and higher) may be reserved for uninitialized pointers.
Even if some location is valid, operating system may still deny access to write to/read from certain location, if that would cause undefined behaviour or violate system safety.
EDIT
I think you might be interested in creating some kind of "GameHack", that allows you to modify amount of resources, number of units, experience level, attributes or anything.
Memory access is not a simple topic. Different OSes use different strategies to prevent security violations. But many thing can be done here, after all there is a lot software for doing such things.
First of all, do you really need to write your own tool? If you just want some cheating, use ArtMoney - it is a great memory editor, that I have been using for years.
But if you really have to write it manually, you need to do some research first.
On Windows, for example, I would start from these:
ReadProcessMemory
WriteProcessMemory
Also, I am quite certain, that one of possible techniques is to pretend, that you are a debugger:
DebugActiveProcess.
EDIT 2
I have done some research and it looks, that on Windows (I assume this is your platform, since you mentioned gaming; can't imagine playing anything on crappy Linux), steps required to write another process' memory are:
1. Enumerate processes: (EnumProcesses)
const size_t MAX_PROC_NUM = 512;
DWORD procIDs[MAX_PROC_NUM] = { 0 };
DWORD idsNum = 0;
if(!EnumProcesses(procIDs, sizeof(DWORD) * MAX_PROC_NUM, &idsNum))
//handle error here
idsNum /= sizeof(DWORD); //After EnumProcesses(), idsNum contains number of BYTES!
2. Open required process. (OpenProcess,GetModuleFileNameEx)
const char* game_exe_path = "E:\\Games\\Spellforce\\Spellforce.exe"; //Example
HANDLE game_proc_handle = nullptr;
DWORD proc_access = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE; //read & write memory, query info needed to get .exe name
const DWORD MAX_EXE_PATH_LEN = 1024;
for(DWORD n = 0 ; n < idsNum ; ++idsNum)
{
DWORD current_id = procIDs[n];
HANDLE current_handle = OpenProcess(proc_access, false, current_id);
if(!current_handle)
{
//handle error here
continue;
}
char current_path[MAX_EXE_PATH_LEN];
DWORD length = GetModuleFileNameEx(current_handle, nullptr, current_path, MAX_EXE_PATH_LEN);
if(length > 0)
{
if(strcmp(current_path, game_exe_path) == 0) //that's our game!
{
game_proc_handle = current_handle;
break;
}
}
CloseHandle(current_handle); //don't forget this!
}
if(!game_proc_handle)
//sorry, game not found
3. Write memory (WriteProcessMemory)
void* pointer = reinterpret_cast<void*>(0x02F70BCC);
int new_value = 5000; //value to be written
BOOL success = WriteProcessMemory(game_proc_handle, pointer, &new_value, sizeof(int), nullptr);
if(success)
//data successfully written!
else
//well, that's... em...
This code is written just 'as is', but I see no errors, so you can use it as your starting point. I also provided links for all functions I used, so with some additional research (if necessary), you can achieve what you are trying to.
Cheers.
When you use,
cout<<*pointer;
the program tries to dereference the value of the pointer and writes the value at the address.
If you want to print just the pointer, use:
cout << pointer;
Example:
int main()
{
int i = 20;
int* p = &i;
std::cout << *p << std::endl; // print the value stored at the address
// pointed to by p. In this case, it will
// print the value of i, which is 20
std::cout << p << std::endl; // print the address that p points to
// It will print the address of i.
}
I have the following problem.
I use the following function to receive a string from a buffer until a newline occurs.
string get_all_buf(int sock) {
int n = 1, total = 0, found = 0;
char c;
char temp[1024*1024];
string antw = "";
while (!found) {
n = recv(sock, &temp[total], sizeof(temp) - total - 1, 0);
if (n == -1) {
break;
}
total += n;
temp[total] = '\0';
found = (strchr(temp, '\n') != 0);
if (found == 0){
found = (strchr(temp, '\r\n') != 0);
}
}
antw = temp;
size_t foundIndex = antw.find("\r\n");
if (foundIndex != antw.npos)
antw.erase ( antw.find ("\r\n"), 2 );
foundIndex = antw.find("\n");
if (foundIndex != antw.npos)
antw.erase ( antw.find ("\n"), 2 );
return answ;
}
So use it like this:
string an = get_all_buf(sClient);
If I create an exe file everything works perfectly.
But if I create a dll and run it using rundll32 the application closes at "string an = get_all_buf(sClient);" without any error message...
I tried to fix this for hours now, and I am currently a bit desperate...
P.S. sorry for obvious errors or bad coding style, I just started learning C++.
char temp[1024*1024];
declares a 1Mb structure on the stack. This may be too large and overflow available stack memory. You could instead give it static scope
static char temp[1024*1024];
or allocate it dynamically
char* temp = (char*)malloc(1024*1024);
// function body
free(temp);
Alternatively, assuming the mention of run32.dll means you're working on Windows, you could investigate keeping it on the stack by using the /STACK linker option. This probably isn't the best approach - you've already found it causes problems when you change build settings or try to target other platforms.
Instead of creating temp variable on the stack, I'd create it dynamically (on the heap), but not using raw malloc and free as showed in a previous answer, but using modern C++ and std::vector:
#include <vector>
std::vector<char> temp(1024*1024);
This is exception safe, and you don't have to pay attention to release the allocated memory: std::vector's destructor will do that automatically (also in case of exceptions thrown).
Instead of sizeof(temp), in your code you can use temp.size() (which will return the count of elements in the vector, and since this is a vector of chars, it will return just the total vector size in chars i.e. in bytes).
You can still use operator[] for std::vector, as you do for raw C arrays.
Note also that if you are building a DLL and the above function is exposed at the DLL interface, since this function has a C++ interface with a STL class (std::string) at the boundary, you must pay attention that both your DLL and your clients are built with dynamic linking to the same CRT, and with the same compiler and the same compiler settings (e.g. you can't mix a DLL built with VS2008/VC9 with a .EXE built with VS2010/VC10, or a release-build DLL with a debug-build EXE built with the same compiler).
When running the release executable only (No problems occur when running through visual studio) my program crashes. When using "attach to process" function visual studio indicates the crash occurred in the following function:
World::blockmap World::newBlankBlockmap(int sideLen, int h){
cout << "newBlankBlockmap side: "<<std::to_string((long long)sideLen) << endl;
cout << "newBlankBlockmap height: "<<std::to_string((long long)h) << endl;
short*** bm = new short**[sideLen];
for(int i=0;i<sideLen;i++){
bm[i] = new short*[h];
for(int j=0;j<h;j++){
bm[i][j] = new short[sideLen];
for (int k = 0; k < sideLen ; k++)
{
bm[i][j][k] = blocks->getAIR_BLOCK();
}
}
}
return (blockmap)bm;
}
Which is called from a child class...
World::chunk* World_E::newChunkMap(World::floatmap north, World::floatmap east, World::floatmap south, World::floatmap west
,float lowlow, float highlow, float highhigh, float lowhigh, bool displaceSides){
World::chunk* c = newChunk(World::CHUNK_SIZE+1,World::HEIGHT);
for (int i = 0; i < World::CHUNK_SIZE ; i++)
{
for (int k = 0; k < World::CHUNK_SIZE ; k++)
{
c->bm[i][0][k] = blocks->getDUMMY_BLOCK();
}
}
c->bm[(int)floor((float)(World::CHUNK_SIZE+1)/2.0f)-1][1][(int)floor((float)(World::CHUNK_SIZE+1)/2.0f)-1] = blocks->getSTONE_BLOCK();
c->bm[(int)ceil((float)(World::CHUNK_SIZE+1)/2.0f)-1][1][(int)floor((float)(World::CHUNK_SIZE+1)/2.0f)-1] = blocks->getSTONE_BLOCK();
c->bm[(int)floor((float)(World::CHUNK_SIZE+1)/2.0f)-1][1][(int)ceil((float)(World::CHUNK_SIZE+1)/2.0f)-1] = blocks->getSTONE_BLOCK();
c->bm[(int)ceil((float)(World::CHUNK_SIZE+1)/2.0f)-1][1][(int)ceil((float)(World::CHUNK_SIZE+1)/2.0f)-1] = blocks->getSTONE_BLOCK();
return c;
}
where...
class World {
public: typedef short*** blockmap;
...
The line which VS points at is...
short*** bm = new short**[sideLen];
The "attach to process" function stats the Local variables are...
sideLen = 1911407648
h = 0
which is what i did NOT expect, but the cout outputs 9 and 30 respectively, which was expected.
I am aware that most "crashes in release only" problems are due to uninitialized variables, however, I fail to see that related here.
The only error message I get is...
Windows has triggered a breakpoint in Blocks Project.exe.
This may be due to a corruption of the heap
I am stumped on this problem, what's the error? how can I better debug release executable?
I can post more code if needed, however, bear in mind there is a lot of it.
Thank you in advanced.
"And I don't see World::newBlankBlockmap() called from that second chunk of code. – Michael Burr", I forgot that bit, here you go...
World::chunk* World::newChunk(int side, int height){
cout << "newChunk side: "<<std::to_string((long long)side) << endl;
cout << "newChunk height: "<<std::to_string((long long)height) << endl;
chunk* ch = new chunk();
ch->bm = newBlankBlockmap(side,height);
ch->fm = newBlankFloatmap(side);
return ch;
}
where...
struct chunk {
blockmap bm;
floatmap fm;
};
as defined in the World class
To reiterate what the comments where hinting at: From what you've posted, you're code seems to be badly structured. Triple pointer constructs like short*** are almost impossible to debug and should be avoided at all costs. The heap corruption error message you got suggests that you have a bad memory access somewhere in your code, which is impossible to find automatically with your current setup.
Your only options at this point are to either dig through your entire code manually, until you've found the bug, or start refactoring. The latter might seem like the more time-consuming now, but it won't be if you plan to work with this code in the future.
Consider the following as possible hints for a refactoring:
Don't use plain arrays for storing values. std::vector is just as effective and a lot easier to debug.
Avoid plain new and delete. In modern C++ with the STL containers and smart pointers, plain memory allocation should only happen in very rare exceptional cases.
Always range-check your array access operations. If you worry about performance, use asserts which disappear in release builds, but be sure the checks are there when you need them for debugging.
Modeling three-dimensional arrays in C++ can be tricky, since operator[] only offers support for one-dimensional arrays. A nice compromise is using operator() instead, which can take an arbitrary number of indices.
Avoid C-style casts. They can be very unpredictable. Use the C++ casts static_cast, dynamic_castand reinterpret_cast instead. If you find yourself using reinterpret_cast regularly, you probably have a mistake in your design somewhere.
There is a problem in this line short*** bm = new short**[sideLen];. The memory is allocated for sideLen elements, but the assignment line bm[i][j][k] = blocks->getAIR_BLOCK(); requires an array having size sideLen * sideLen * h. To fix this problem changing of the 1st line to short*** bm = new short**[sideLen * sideLen * h]; is required.