블로그 이전했습니다. https://jeongzero.oopy.io/
[reversing.kr] Music Player.exe
본문 바로가기
워게임/reversing.kr

[reversing.kr] Music Player.exe

728x90

1. 문제


1) 문제 확인

음악을 재생할수 있다. VBA로 만들어졌고 따로 패킹은 안돼있다. 이번 목표는 재생 시간이 1분으로 제한된것을 우회하는 것이다

다음과 같이 msgbox가 뜬다. 저기를 확인해보자.

msgbox를 사용하는 부분은 총 4개이다. 전부 bp를 걸고 보면 어디서 1분 미리듣기만 가능합니다를 호출하는지 알수 있다. (0x4045d8임)

2) 코드흐름 파악

/* WARNING: Globals starting with '_' overlap smaller symbols at the same address */

void __cdecl FUN_004044c0(uint param_1)

{
  int iVar1;
  undefined4 uVar2;
  int *piVar3;
  int *piVar4;
  undefined4 *in_FS_OFFSET;
  ushort uVar5;
  int local_c4;
  double local_c0;
  int local_a8 [9];
  undefined4 local_84 [2];
  undefined *local_7c;
  undefined4 local_74 [2];
  undefined *local_6c;
  undefined4 local_64 [2];
  undefined4 local_5c;
  undefined4 local_54 [2];
  undefined4 local_4c;
  undefined4 local_44 [2];
  undefined4 local_3c;
  undefined4 local_34 [4];
  undefined4 local_24;
  undefined4 local_20;
  int local_1c;
  undefined4 uStack24;
  undefined *puStack20;
  undefined *local_10;
  undefined *local_c;
  uint local_8;
  
  puStack20 = &LAB_004012b6;
  uStack24 = *in_FS_OFFSET;
  *(undefined4 **)in_FS_OFFSET = &uStack24;
  local_10 = &stack0xffffff30;
  local_c = &DAT_004011d8;
  local_8 = param_1 & 1;
  piVar4 = (int *)(param_1 & 0xfffffffe);
  (**(code **)(*piVar4 + 4))(piVar4);
  local_20 = 0;
  local_24 = 0;
  local_34[0] = 0;
  local_44[0] = 0;
  local_54[0] = 0;
  local_64[0] = 0;
  local_74[0] = 0;
  local_84[0] = 0;
  local_a8[0] = 0;
  if (piVar4[0xd] == 0) {
    __vbaNew2(&DAT_0040186c,piVar4 + 0xd);
  }
  piVar3 = (int *)piVar4[0xd];
  iVar1 = (**(code **)(*piVar3 + 0x44))(piVar3,local_a8);
  uVar5 = 0;
  if (iVar1 < 0) {
    __vbaHresultCheckObj(iVar1,piVar3,&DAT_0040276c,0x44);
  }
  local_1c = local_a8[0];
  if (local_a8[0] < 60000) {
    if (local_a8[0] != -1) {
      (**(code **)(*piVar4 + 0x6f8))(piVar4,local_a8[0]);
      local_c0 = (double)local_1c;
      if (_DAT_00407000 != 0) {
        _adj_fdiv_m64(0,0x40590000);
      }
      if ((uVar5 & 0xd) != 0) {
                    /* WARNING: Could not recover jumptable at 0x004012bc. Too many branches */
                    /* WARNING: Treating indirect jump as call */
        __vbaFPException();
        return;
      }
      iVar1 = __vbaFpI4();
      if (600 < iVar1) {
        __vbaStrCopy();
      }
      uVar2 = (**(code **)(*piVar4 + 0x31c))(piVar4);
      piVar3 = (int *)__vbaObjSet(&local_24,uVar2);
      local_c4 = *piVar3;
      uVar2 = __vbaI2I4();
      iVar1 = (**(code **)(local_c4 + 0xbc))(piVar3,uVar2);
      if (iVar1 < 0) {
        __vbaHresultCheckObj(iVar1,piVar3,&DAT_00402b58,0xbc);
      }
      __vbaFreeObj();
    }
    if (piVar4[0xd] == 0) {
      __vbaNew2(&DAT_0040186c,piVar4 + 0xd);
    }
    piVar4 = (int *)piVar4[0xd];
    iVar1 = (**(code **)(*piVar4 + 0x44))(piVar4,local_a8);
    if (iVar1 < 0) {
      __vbaHresultCheckObj(iVar1,piVar4,&DAT_0040276c,0x44);
    }
    if (0xea6a < local_a8[0]) {
      local_6c = &DAT_00402bdc;
      local_74[0] = 8;
      rtcVarBstrFromAnsi(local_34,0x72);
      local_84[0] = 8;
      local_7c = &DAT_00402be4;
      uVar2 = __vbaVarCat(local_44,local_34,local_74);
      uVar2 = __vbaVarCat(local_54,local_84,uVar2);
      __vbaStrVarMove(uVar2);
      __vbaStrMove();
      __vbaStrCopy();
      __vbaFreeStr();
      __vbaFreeVarList(3,local_34,local_44,local_54);
    }
  }
  else {
    iVar1 = (**(code **)(*piVar4 + 0x708))(piVar4);
    if (iVar1 < 0) {
      __vbaHresultCheckObj(iVar1,piVar4,&DAT_004025c0,0x708);
    }
    local_5c = 0x80020004;
    local_4c = 0x80020004;
    local_3c = 0x80020004;
    local_64[0] = 10;
    local_54[0] = 10;
    local_44[0] = 10;
    local_6c = &LAB_00402bac;
    local_74[0] = 8;
    __vbaVarDup();
    rtcMsgBox(local_34,0x40,local_44,local_54,local_64);
    __vbaFreeVarList(4,local_34,local_44,local_54,local_64);
  }
  return;
}

0x4045d8은 위 rtcMsgBox()의 주소이다. 따라서 위 코드에서 1분 체크 로직이 들어있을 것이다. 맨 위를 보면 if -else 로 분기되는데, if문 안으로 분기되게 변경을 하면 될것이다

2. 접근방법


저기 JL 부분을 무조건 if문 안으로 들어오게 하기 위해 JMP로 코드패치를 하면 된다.

하지만 그렇게 되면 1분이 됬을때 에러가 하나 발생하는데 그거까지 우회해야한다.

      __vbaNew2(&DAT_0040186c,piVar4 + 0xd);
    }
    piVar4 = (int *)piVar4[0xd];
    iVar1 = (**(code **)(*piVar4 + 0x44))(piVar4,local_a8);
    if (iVar1 < 0) {
      __vbaHresultCheckObj(iVar1,piVar4,&DAT_0040276c,0x44);
    }
    ....

해당 에러는 위 함수 내부에서 발생한다. 이걸 어케 찾았냐면 걍 노가다로 찾았다. 어디서 에러나는지 모르겠어서 에러처리를 할법한 부분을 모두 확인했는데, 일단 저기랑

if ((uVar5 & 0xd) != 0) {
                    /* WARNING: Could not recover jumptable at 0x004012bc. Too many branches */
                    /* WARNING: Treating indirect jump as call */
        __vbaFPException();
        return;
      }

여기다. 위 두 곳은 59초 까지는 절로 가진 않지만, 59초-1분이 됐을때 ...checkObj() 로 뛰게 된다. 따라서 저기도 패치하면 된다.

				004046a7 85  c0           TEST       EAX ,EAX
        004046a9 db  e2           FNCLEX
        004046ab 7d  12           JGE        LAB_004046bf // 여기를 JMP로 변경

3. 풀이


4. 몰랐던 개념


728x90

'워게임 > reversing.kr' 카테고리의 다른 글

[reversing.kr] ImagePrc  (0) 2020.12.15
[reversing.kr] Replace  (0) 2020.12.14
[reversing.kr] easy elf  (0) 2020.12.10
[reversing.kr] easy keygen  (0) 2020.12.08
[reversing.kr] easy crack  (0) 2020.12.07