Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • 해당 함수는 다음과 같은 기능을 합니다.

    • player 변수의 값을 이용해 플레이어의 마크를 결정합니다.

    • saveMarkofBoard() 함수와 마크를 저장할 좌표 값(row, col)을 이용해gameinfo.Board[] 영역에 값을 저장합니다.

    • 각종 함수를 이용해 플레이어가 마크를 저장하길 원하는 위치 값이 타당한지 확인합니다.

      • CheckBoardArea(), GetMarkForBoard(), checkLocation(), ...

    • 입력한 위치 값이 정상적이지 않으면 메시지를 출력하고 프로그램을 종료합니다.

    • 입력한 위치

      값가

      값이 정상적이라면 해당 gameInfo를 gHistory[]에 저장합니다.

      • "operator new(0x80)" 코드에 의해 Heap 영역을 할당합니다.

      • 할당된 Heap 영역의 주소 값을 gHistory[]변수에 저장합니다.

      • 즉, 사용자가 입력한 좌표 값이 Heap 영역에 저장됩니다.

  • 취약성은 여기서 발생합니다.

    • GameInfo 구조체를 사용하는 gHistory[]의 크기는 364 입니다.

    • gHistory[] 배열에 저장된 번호가 364를 넘는지에 대한 확인이 없습니다.

    • 즉, 유저가 입력한 값이 364회가 넘으면 gPlayerGameInfo 영역에 Overflow됩니다.

Code Block
titleSetMarkForBoard()
signed __int64 __fastcall SetMarkForBoard(GameInfo *gameinfo, unsigned int inputRow, unsigned int inputCol, int player, unsigned __int8 printOpt)
{
  signed __int64 result; // rax
  signed int mark; // eax MAPDST
  bool v7; // al
  GameInfo *historyCount; // rax
  GameInfo *saveGameInfo; // ST30_8
  signed int i; // [rsp+24h] [rbp-2Ch]
  unsigned int row; // [rsp+28h] [rbp-28h]
  unsigned int col; // [rsp+2Ch] [rbp-24h]

  if ( (unsigned __int8)GetMarkForBoard((__int64)gameinfo, inputRow, inputCol) == '.' )
  {
    if ( player == 1 )
      mark = 'O';
    else
      mark = 'X';
    saveMarkofBoard((__int64)gameinfo, inputRow, inputCol, mark);
    gameinfo->rowNumber = inputRow;
    gameinfo->colNumber = inputCol;
    for ( i = 0; i <= 3; ++i )
    {
      row = dword_404FE0[i] + inputRow;
      col = dword_404FF0[i] + inputCol;
      v7 = (unsigned __int8)CheckBoardArea(row) ^ 1 || (unsigned __int8)CheckBoardArea(col) ^ 1;
      if ( !v7
        && (char)GetMarkForBoard((__int64)gameinfo, row, col) == 0xA7 - mark
        && (unsigned int)checkLocation((__int64)gameinfo, row, col) == 0 )
      {
        sub_4024C2((__int64)gameinfo, row, col);
      }
    }
    if ( (unsigned int)checkLocation((__int64)gameinfo, inputRow, inputCol) == 0 )
    {
      if ( !printOpt )
        print("Why you do this :((");
      result = 0LL;
    }
    else if ( (unsigned __int8)sub_402528((__int64)gameinfo, printOpt) )
    {
      if ( !printOpt )
        print("Wanna Ko Fight?");
      result = 0LL;
    }
    else
    {
      if ( printOpt != 1 )
      {
        LODWORD(gameinfo->player) = mark;
        historyCount = (GameInfo *)operator new(0x80uLL);
        *historyCount = *gameinfo;
        saveGameInfo = historyCount;
        LODWORD(historyCount) = gHistoryCount++;
        gHistory[(signed int)historyCount] = saveGameInfo;
      }
      result = 1LL;
    }
  }
  else
  {
    if ( !printOpt )
      print("You cheater!");
    result = 0LL;
  }
  return result;
}

...