#include "common.h" #ifdef _AMD64_ #include "../BasicCompiler64/opcode.h" #else #include "../BasicCompiler32/opcode.h" #endif //デバッグ用 #include "debug.h" int Debugging_GetArray( const int *SubScripts,char *array,const Type &type,LONG_PTR *plpOffset); ULONG_PTR Debugging_GetVarPtr(RELATIVE_VAR *pRelativeVar){ extern DWORD ImageBase; extern int MemPos_RWSection; int i2; if(pRelativeVar->dwKind==VAR_GLOBAL){ return ImageBase+MemPos_RWSection+pRelativeVar->offset; } else if( pRelativeVar->dwKind == VAR_REFGLOBAL ){ extern HANDLE hDebugProcess; LONG_PTR lpData; SIZE_T accessBytes; ReadProcessMemory(hDebugProcess, (void *)(ImageBase+MemPos_RWSection+pRelativeVar->offset), &lpData, sizeof(LONG_PTR), &accessBytes); return lpData; } else if(pRelativeVar->dwKind==VAR_LOCAL){ extern HWND hDebugWnd; i2=(int)SendDlgItemMessage(hDebugWnd,IDC_PROCCOMBO,CB_GETCURSEL,0,0); i2=pobj_dti->iProcLevel-i2; if(pobj_dti->lplpSpBase[i2]==0) return 0; return pobj_dti->lplpSpBase[i2]+pRelativeVar->offset; } else if( pRelativeVar->dwKind == VAR_REFLOCAL ){ extern HWND hDebugWnd; i2=(int)SendDlgItemMessage(hDebugWnd,IDC_PROCCOMBO,CB_GETCURSEL,0,0); i2=pobj_dti->iProcLevel-i2; if(pobj_dti->lplpSpBase[i2]==0) return 0; extern HANDLE hDebugProcess; LONG_PTR lpData; SIZE_T accessBytes; ReadProcessMemory(hDebugProcess, (void *)(pobj_dti->lplpSpBase[i2]+(int)pRelativeVar->offset), &lpData, sizeof(LONG_PTR), &accessBytes); return lpData; } else if(pRelativeVar->dwKind==VAR_DIRECTMEM){ return pRelativeVar->offset; } return 0; } bool Debugging_SetRelativeOffset( Type &type,RELATIVE_VAR *pRelativeVar,char *lpPtrOffset){ int array_num; _int64 i64data; if( !StaticCalculation( true, lpPtrOffset, 0, &i64data, Type(), 1 ) ){ return false; } if( type.IsReal() ){ double dbl; memcpy(&dbl,&i64data,sizeof(double)); i64data=(_int64)dbl; } array_num=(int)i64data; if( type.PtrLevel() ){ type.PtrLevelDown(); array_num *= type.GetSize(); } else{ //エラー return false; } extern HANDLE hDebugProcess; LONG_PTR lpData; SIZE_T accessBytes; lpData=Debugging_GetVarPtr(pRelativeVar); if(!ReadProcessMemory(hDebugProcess,(void *)lpData,&pRelativeVar->offset,sizeof(LONG_PTR),&accessBytes)){ return false; } pRelativeVar->dwKind=VAR_DIRECTMEM; pRelativeVar->offset+=array_num; return true; } int Debugging_GetMember( const CClass &objClass,char *member,RELATIVE_VAR *pRelativeVar, Type &resultType, BOOL bPrivateAccess){ int i,i2; //直接参照に切り替え pRelativeVar->offset=(LONG_PTR)Debugging_GetVarPtr(pRelativeVar); pRelativeVar->dwKind=VAR_DIRECTMEM; //クラス、配列の構成要素を解析する char VarName[VN_SIZE]; //変数名 char array[VN_SIZE]; //第1次配列 char lpPtrOffset[VN_SIZE]; //第2次配列 char NestMember[VN_SIZE]; //入れ子メンバ CClass::RefType refType; lstrcpy(VarName,member); if(!GetVarFormatString(VarName,array,lpPtrOffset,NestMember, refType ) ) return 0; //////////////////////////// // メンバオフセットを取得 //////////////////////////// int offset = objClass.GetMemberOffset( VarName, &i ); if(i==objClass.iMemberNum) return 0; //アクセシビリティをチェック if((bPrivateAccess==0&&objClass.ppobj_Member[i]->dwAccess==ACCESS_PRIVATE)|| objClass.ppobj_Member[i]->dwAccess==ACCESS_NON){ return 0; } else if(bPrivateAccess==0&&objClass.ppobj_Member[i]->dwAccess==ACCESS_PROTECTED) return 0; resultType = *objClass.ppobj_Member[i]; //ポインタ変数の場合 if( resultType.IsPointer() ){ if(objClass.ppobj_Member[i]->SubScripts[0]==-1){ lstrcpy(lpPtrOffset,array); array[0]=0; } } else{ if(lpPtrOffset[0]) return 0; } pRelativeVar->offset+=offset; if(array[0]){ //配列オフセット i2=Debugging_GetArray( objClass.ppobj_Member[i]->SubScripts, array, resultType, &pRelativeVar->offset); if(i2==0){ //式エラー return 0; } if(i2==-1){ //アクセスエラー return -1; } } else if(objClass.ppobj_Member[i]->SubScripts[0]!=-1){ resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR ); } if(NestMember[0]){ //入れ子構造の場合 if( resultType.IsObject() || resultType.IsStruct() ){ if( refType != CClass::Dot ) return 0; if( resultType.IsObject() ){ extern HANDLE hDebugProcess; LONG_PTR lpData; SIZE_T accessBytes; lpData=Debugging_GetVarPtr(pRelativeVar); if(!ReadProcessMemory(hDebugProcess,(void *)lpData,&pRelativeVar->offset,sizeof(LONG_PTR),&accessBytes)) return -1; pRelativeVar->dwKind=VAR_DIRECTMEM; } } else if( resultType.IsObjectPtr() || resultType.IsStructPtr() ){ //構造体ポインタ型メンバ変数 if(lpPtrOffset[0]){ if( refType != CClass::Dot ) return 0; //直接参照に切り替え Debugging_SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset); lpPtrOffset[0]=0; } else{ if( refType != CClass::Pointer ) return 0; extern HANDLE hDebugProcess; LONG_PTR lpData; SIZE_T accessBytes; lpData=Debugging_GetVarPtr(pRelativeVar); if(!ReadProcessMemory(hDebugProcess,(void *)lpData,&pRelativeVar->offset,sizeof(LONG_PTR),&accessBytes)) return -1; pRelativeVar->dwKind=VAR_DIRECTMEM; } } i2=Debugging_GetMember(objClass.ppobj_Member[i]->GetClass(), NestMember, pRelativeVar, resultType, 0); if(i2==0){ //式エラー return 0; } if(i2==-1){ //アクセスエラー return -1; } } if(lpPtrOffset[0]){ Debugging_SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset); } return 1; } int Debugging_GetArray( const int *SubScripts,char *array,const Type &type,LONG_PTR *plpOffset){ extern HANDLE hHeap; int i,i2,i3,i4,i5,array_offset; char temporary[VN_SIZE],*pParm[MAX_PARMS]; for(i=0,i2=0,i3=0;;i++,i2++){ if(array[i]=='('){ i4=GetStringInPare(temporary+i2,array+i); i+=i4-1; i2+=i4-1; continue; } if(array[i]=='['){ i4=GetStringInBracket(temporary+i2,array+i); i+=i4-1; i2+=i4-1; continue; } if(array[i]==','||array[i]=='\0'){ if(SubScripts[i3]==-1){ for(i3--;i3>=0;i3--) HeapDefaultFree(pParm[i3]); return 0; } temporary[i2]=0; pParm[i3]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1); lstrcpy(pParm[i3],temporary); i3++; if(array[i]=='\0'){ if(SubScripts[i3]!=-1){ for(i3--;i3>=0;i3--) HeapDefaultFree(pParm[i3]); return 0; } break; } i2=-1; continue; } temporary[i2]=array[i]; } array_offset=0; for(i=i3-1;i>=0;i--){ _int64 i64data; Type resultType; bool isMemoryAccessError; if( !StaticCalculation(true, pParm[i],0,&i64data,resultType,1, &isMemoryAccessError ) ){ //式エラー return 0; } if(isMemoryAccessError){ //アクセスエラー return -1; } if(resultType.IsReal()){ double dbl; memcpy(&dbl,&i64data,sizeof(double)); i64data=(_int64)dbl; } i5=(int)i64data; for(i2=i+1,i4=1;i2localVars ){ if( pVar->GetName() == "_System_LocalThis" ){ return pVar->offset; } } return 0; } int Debugging_GetVarOffset( char *variable,RELATIVE_VAR *pRelativeVar, Type &resultType, int *pss){ extern HANDLE hDebugProcess; int i,i2,i3; char member[VN_SIZE],VarName[VN_SIZE],array[VN_SIZE],lpPtrOffset[VN_SIZE]; LONG_PTR lpData; SIZE_T accessBytes; lstrcpy(VarName,variable); CClass::RefType refType; GetVarFormatString(VarName,array,lpPtrOffset,member,refType); const int *pSubScripts; bool isArray; ///////////////// // ローカル変数 ///////////////// const Variable *pVar = UserProc::CompilingUserProc().localVars.Find( VarName ); if( pVar ){ //ポインタ変数の場合 if( pVar->IsPointer() ){ if( !pVar->IsArray() ){ lstrcpy(lpPtrOffset,array); array[0]=0; } } else{ if(lpPtrOffset[0]) return 0; } pRelativeVar->offset = pVar->offset; if( pVar->IsRef() ){ pRelativeVar->dwKind=VAR_REFLOCAL; } else{ pRelativeVar->dwKind=VAR_LOCAL; } resultType = *pVar; isArray = pVar->IsArray(); pSubScripts = pVar->GetSubScriptsPtr(); } else{ if(pobj_CompilingClass){ /////////////////////// // クラスメンバの参照 /////////////////////// if(memicmp(variable,"This.",5)==0){ //Thisオブジェクトのメンバを参照するとき SlideString(variable+5,-5); lstrcpy(VarName,variable); } else{ //クラス内メンバを参照するとき(通常) for(i=0;iiMemberNum;i++){ if(lstrcmp(VarName,pobj_CompilingClass->ppobj_Member[i]->name)==0) break; } if(i==pobj_CompilingClass->iMemberNum) goto NonClassMember; } ///////////////////////////// // thisポインタを取得 extern HWND hDebugWnd; i2=(int)SendDlgItemMessage(hDebugWnd,IDC_PROCCOMBO,CB_GETCURSEL,0,0); i2=pobj_dti->iProcLevel-i2; lpData=Debugging_GetThisPtrOffset(pobj_dti->lplpObp[i2]); if(!lpData){ //式エラー return 0; } lpData+=pobj_dti->lplpSpBase[i2]; if(!ReadProcessMemory(hDebugProcess,(void *)lpData,&pRelativeVar->offset,sizeof(LONG_PTR),&accessBytes)){ //メモリにアクセスできないとき return -1; } pRelativeVar->dwKind=VAR_DIRECTMEM; i3=Debugging_GetMember(*pobj_CompilingClass,variable,pRelativeVar,resultType,1); if(i3==0){ //式エラー return 0; } if(i3==-1){ //アクセスエラー return -1; } return 1; } NonClassMember: /////////////////// // グローバル変数 /////////////////// const Variable *pVar = globalVars.Find( VarName ); if( !pVar ){ //一致しないとき return 0; } //ポインタ変数の場合 if( pVar->IsPointer() ){ if( !pVar->IsArray() ){ lstrcpy(lpPtrOffset,array); array[0]=0; } } else{ if(lpPtrOffset[0]) return 0; } pRelativeVar->offset=pVar->offset; if(pVar->IsRef()) pRelativeVar->dwKind=VAR_REFGLOBAL; else pRelativeVar->dwKind=VAR_GLOBAL; resultType = *pVar; isArray = pVar->IsArray(); pSubScripts=pVar->GetSubScriptsPtr(); } if(array[0]==0&&isArray){ //配列の先頭ポインタを示す場合 resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR ); if(pss) memcpy(pss,pSubScripts,MAX_ARRAYDIM*sizeof(int)); return 1; } if(array[0]){ i3=Debugging_GetArray(pSubScripts,array,resultType,&pRelativeVar->offset); if(i3==0){ //式エラー return 0; } if(i3==-1){ //アクセスエラー return -1; } } if(member[0]){ if( resultType.IsObject() || resultType.IsStruct() ){ //実態オブジェクトのメンバを参照(obj.member) if( refType != CClass::Dot ){ return 0; } i3=Debugging_GetMember(resultType.GetClass(),member,pRelativeVar,resultType,0); if(i3==0){ //式エラー return 0; } if(i3==-1){ //アクセスエラー return -1; } } else if( resultType.IsObjectPtr() || resultType.IsStructPtr() ){ //ポインタオブジェクトが示すメンバを参照 if(lpPtrOffset[0]){ //pObj[n].member if( refType != CClass::Dot ) return 0; Debugging_SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset); i3=Debugging_GetMember(resultType.GetClass(),member,pRelativeVar,resultType,0); if(i3==0){ //式エラー return 0; } if(i3==-1){ //アクセスエラー return -1; } } else{ //pObj->member if( refType != CClass::Pointer ) return 0; pRelativeVar->offset=Debugging_GetVarPtr(pRelativeVar); pRelativeVar->dwKind=VAR_DIRECTMEM; if(!ReadProcessMemory(hDebugProcess,(void *)pRelativeVar->offset,&lpData,sizeof(LONG_PTR),&accessBytes)) return -1; pRelativeVar->offset=lpData; i3=Debugging_GetMember(resultType.GetClass(),member,pRelativeVar,resultType,0); if(i3==0){ //式エラー return 0; } if(i3==-1){ //アクセスエラー return -1; } } } else{ return 0; } return 1; } if(lpPtrOffset[0]){ if(!Debugging_SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset)) return 0; } return 1; }