반응형

프로그램에서 발생 시키는 예외를 처리하고 콜 스택을 확인해 보자.

 

Music_Player.zip
9.52MB

 

 

※ 참고

Music_Player.exe.dd32
0.02MB

x32dbg로 분석하며 정리한 comments 파일

[x32dbg설치 위치]\release\x32\db에 복사해 넣으면 comment로 파일 내 중요한 위치의 정보가 표시된다.

 

 

1분 듣기 제한이 있는 Music_Player에서 00404563에서 eax와 60,000을 비교한 후 eax가 60,000보다 작으면 0040456B에 의해 4045FE로 점프하게 된다. 그래서 이 부분을 무조건 점프하도록 jl에서 jmp로 바꾸면 60초 후, 아래와 같은 Run-time error가 발생한다.

 

 

이 상태에서 x32dbg로 돌아와 디버기를 Pause한다.

 

 

그러면 760D10CC에서 멈추게 되는데 이 부분은 중요하지 않다.

 

 

Call Stack 윈도우에서 우클릭 - Show Suspected Call Stack Frame을 클릭한다.

 

 

위에서부터 살펴보면 music_player의 004046BF 주소로 돌아가야 한다는 것을 알 수 있다. 004046BF로 가보자.

 

 

004046BF 바로 위 주소 004046B9에서 call dword ptr ds:[<__vbaHresultCheckObj>] 명령에 의해 Run-time error가 발생한것을 알 수 있다.

 

 

이번엔 Run-time error가 발생할 때 x32dbg가 자동으로 break를 걸도록 해 보자.

 

Options - Preferences - Exceptions - Unknown exceptions 를 선택하고 First chance와 Debugger를 선택하고 저장한다.

 

마찬가지로 0040456B에서 무조건 점프 하도록 명령문을 jmp 0x004045FE 로 바꾸고 음악 파일을 60초 이상 플레이한다.

 

 

Run-time error 윈도우가 뜨기 전, 위 그림과 같이 자동으로 브레이크가 걸린다. 이 부분은 중요하지 않으므로 콜 스택 윈도우로 가보자.

 

 

이번에도 우클릭 - Show Suspected Call Stack Frame을 클릭하면 위 그림과 같이 music_player로 돌아갈 주소 004046BF가 표시되어 있다.

 

 

004046B9 call dword ptr ds:[<__vbaHresultCheckObj>] 명령이 실행되지 않도록 아래 그림과 같이 004046AB의 jge를 jmp로 바꾼다.

 

 

2025.07.18 - [Reverse Engineering] - [Ghidra] iVar1 = (**(code **)(*piVar3 + 0x44))(piVar3,local_a8)의 의미

 

 

Music_Player에서 60,000과 비교하는 플레이 시간을 가져오는 함수를 조금 더 살펴보자.

 

 

00404563에서 eax와 60,000을 비교하기 전, 0040455D에서 [ebp-A4]의 값이 eax로 복사 되는걸 볼 수 있다.

 

 

그전에 00404539~00404545에서 [ebp-A4]의 주소값이 eax로 복사되고 스택에 push되어 함수가 호출된다. [ebp-A4]의 주소는 0019F9F0이고 호출되는 함수에서는 ebp+C 에서 이 값을 찾을 수 있다. 여기서 60,000과 비교할 값을 가져온다는걸 추측할 수 있다.

00404545에 브레이크 포인트를 걸고 어떤 함수로 이동하는지 살펴보자.

 

 

Step Into로 한 스텝 들어가 보면 여러 함수의 목록 테이블 같은 코드로 이동하게 된다. 그 중 00401A38은 4055A0로 이동하는 jmp명령이다.

 

4055A0는 HScrollBar의 위치를 가져오는 함수다.

 

플레이가 시작되면 음악 파일의 재생 위치 위치로 시간을 가져 오는게 아닌, 타이머를 1초 간격으로 호출하며 스크롤 바를 이동 시키고 다시 그 스크롤 바의 위치로 재생 시간을 구하는게 아닌가 싶다. (VB Decompiler 분석)

 

 

 

004055A0 함수의 내용을 보면 004055F5 에서 어떤 함수 호출 후 [ebp+C]의 값을 edx로 복사하고 004055FE 에서 그 함수의 리턴값을 edx가 가리키는 위치로 복사하는 것을 볼 수 있다. 여기서 [ebp+C]는 이전 함수에서 60,000과 비교할 값을 저장할 [ebp-A4]의 위치 값(0019F9F0)이다. 바로 플레이 시간이 저장되는 것이다.

 

ebp+C 에 들어있는 값 = 0019F9F0

 

 

그런데 004055FE 명령 전 까지 진행 된 상태에서 레지스터를 보면 EBX, EDI 값이 0인걸 알 수 있다.

 

 

그래서 004055FE mov dword ptr ds:[edx],eaxmov dword ptr ds:[edx],edi로 바꾸면 플레이 시간이 항상 0으로 인식될 것이다. 하지만 이렇게 하면 HScrollBar도 항상 0인 위치를 가리키게 된다.

 

반응형
Posted by J-sean
:
반응형

Keras 관련 에러를 몇 가지 확인하고 해결해 보자.

 

1)

dense = keras.layers.Dense(10, activation='softmax', input_shape=(784, ))

위 명령을 실행하면 아래와 같은 경고가 출력된다.

UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.

경고이므로 무시하고 넘어간다.


model = keras.Sequential(dense)
이어서 위 명령은 아래와 같은 에러가 출력된다.

TypeError: 'Dense' object is not iterable
아래와 같이 바꿔서 해결한다.
model = keras.Sequential([dense])

 

아니면 처음부터 아래와 같이 입력하면 경고나 에러 없이 진행 된다.
model = keras.Sequential([keras.Input(shape=(784, )), keras.layers.Dense(10, activation='softmax')])

 

2)

model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')

위 명령을 실행하면 아래와 같은 에러가 출력된다.

ValueError: Expected `metrics` argument to be a list, tuple, or dict. Received instead: metrics=accuracy of type <class 'str'>

아래와 같이 바꿔서 해결한다.
model.compile(loss='sparse_categorical_crossentropy', metrics=['accuracy'])

 

 

 

※ 참고

혼자 공부하는 머신러닝 + 딥러닝

 

반응형
Posted by J-sean
:
반응형

 

2022.0118 - [Unity] - Unity3D - 유니티3D with AdMob 광고의 내용을 진행하다 보면 예상치 못한 에러를 만날 수 있다. 몇 가지 에러를 해결해 보자.

 

Resolving Android Dependencies 과정 중 발생하는 에러

환경 변수에 JAVA_HOME이 등록되지 않아 발생하는 에러다.

 

유니티 설치 폴더에 있는 OpenJDK 경로를 JAVA_HOME 변수로 등록한다.

 

Google.IOSResolver.dll을 로드할 수 없어 발생하는 에러

안드로이드 앱을 개발하기 위해 iOS Build Support를 설치하지 않아 발생하는 에러다.

 

Unity Hub를 실행한다.

 

 

설치되어 있는 Unity 아이콘 오른쪽 점(...)을 클릭하고 Add Modules를 선택한다.

 

iOS Build Support를 선택하고 DONE을 클릭해 설치한다.

 

반응형
Posted by J-sean
:
반응형

입력 문자열 형식 에러 잡는 방법 두 가지를 알아보자.

Try-Catch 구문을 사용하거나 TryParse()를 사용할 수 있다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace CS
{
    using static System.Console;
 
    class Program
    {
        static void Main(string[] args)
        {
            int age;
            string ageText;
 
            Write("Enter your age: ");
            ageText = ReadLine();
 
            // Try-Catch
            try
            {
                age = int.Parse(ageText);
                WriteLine($"You are {age * 12} months old.");
            }
            catch (FormatException exc)
            {
                WriteLine($"The age entered, {ageText}, is not valid: {exc.Message}");
            }
            catch (Exception exc)
            {
                WriteLine($"Unexpected error: {exc.Message}");
            }
            finally
            {
                WriteLine("Goodbye.");
            }
 
            // TryParse()
            if (int.TryParse(ageText, out age))
            {
                WriteLine($"You are {age * 12} months old.");
            } else
            {
                WriteLine($"The age entered, {ageText}, is not valid.");
            }
        }
    }
}
 

 

소스를 입력하고 빌드한다.

 

실행하고 숫자를 입력하면 아무 문제없이 출력된다.

 

숫자가 아닌 문자가 입력되면 에러가 발생하고 잘 처리된다.

 

반응형
Posted by J-sean
:

Qt platform plugin error fix

C, C++ 2021. 9. 26. 15:14 |
반응형

Qt로 작성된 프로그램을 Qt Creator에서 실행하면 잘 되지만 실행 파일을 직접 실행하면 아래와 같은 에러가 발생한다.

 

 

This application failed to start because no Qt platform plugin could be initialized. 라는 메세지에서 알 수 있는 것 처럼 platform plugin이 없기 때문이다.

 

Qt 설치 폳더에서 platforms 폴더를 복사한다.

 

실행 파일이 있는 폴더에 붙여 넣는다.

Debug, Release 모두 동일하다.

그 외, 필요한 dll 파일도 모두 복사해 넣고 실행하면 문제없이 실행된다.

 

반응형
Posted by J-sean
: