hhkb.dev

BLOG

2025-10-24 / 어셈블리 · 10

문자열 참조와 교차 참조(X-Ref) 분석

바이너리를 main부터 끝까지 순서대로 보는 방식은 규모가 커질수록 비효율적이다. 보통은 더 눈에 띄는 단서를 먼저 잡고 거꾸로 따라가는 편이 빠르다. 그중 가장 직관적인 단서가 문자열이다.

대부분 프로그램은 사용자에게 뭔가를 보여주기 때문에 문자열을 포함한다.

  • Password Incorrect
  • Success!

이 문자열은 보통 컴파일 후 .rodata.data에 들어간다. Ghidra에서 Search -> For Strings를 쓰면 한 번에 모아서 볼 수 있다.

2. 교차 참조(Cross-Reference, X-Ref)

문자열 자체보다 더 중요한 건, 그 문자열을 누가 쓰는지다. Ghidra에서 문자열을 선택하고 XREF를 보면, 이 값을 참조하는 함수와 주소를 바로 찾을 수 있다.

                             XREF[1]:     check_password:00401050 (R)  
ds "Correct!"

이 정보는 check_password 함수의 00401050 위치에서 이 문자열을 읽는다는 뜻이다. 그 지점으로 가면 인증 성공 분기 같은 핵심 로직을 바로 찾을 수 있다.

if (is_valid) {
    puts("Correct!"); // <- X-Ref를 통해 도달한 위치
}

이 방식의 장점은 인증 로직 같은 핵심 분기를 빠르게 특정할 수 있다는 점이다. 다만 문자열이 암호화돼 있거나 동적으로 만들어지면, 문자열 검색만으로는 부족해서 API 추적 같은 다른 기법이 필요하다.

스택 문자열 (Stack Strings)
일부 악성코드나 보호 기법은 문자열 검색을 피하려고 문자열을 한 글자씩 스택에 넣어 동적으로 만든다.

mov [rbp-0x4], 'F'
mov [rbp-0x3], 'l'
mov [rbp-0x2], 'a'
mov [rbp-0x1], 'g'

이런 경우에는 단순 문자열 검색으로 Flag가 보이지 않는다. 메모리 덤프나 디컴파일 코드를 같이 봐야 한다.