그래서 내가 해야 할 일은 물리적 메모리에서 직접 커널 기호를 읽는 것입니다.다음 줄을 사용하여 변수(기호)를 내보내는 커널 모듈을 작성했습니다.
int test_var = 5;
EXPORT_SYMBOL(test_var);
cat /proc/kallsyms | grep test_var
내가 사용 하여
ffffffffc04d6064 r __kstrtab_test_var [smigenerator]
ffffffffc04d606d r __kstrtabns_test_var [smigenerator]
ffffffffc04d6054 r __ksymtab_test_var [smigenerator]
ffffffffc04d7000 D test_var [smigenerator]
따라서 내 기호는 에 저장됩니다 0xc04d7000
. 실행하면 sudo devmem2 0xc04d7000
해당 값(=5)을 얻게 됩니다. 그렇죠?
잘못된! 이 주소를 읽으면 가 반환됩니다 0xFF300A24
.변수가 저장될 메모리 주소를 읽을 때 변수 값을 얻지 못하는 이유는 무엇입니까?
커널 기본 주소에 대한 내용을 읽었으며 kallsyms에서 얻은 이 주소는 커널 기본 주소에 추가되어야 하는 오프셋입니다. 이것이 사실인지는 확실하지 않지만 그렇다면 이 커널 기본 주소를 어떻게 얻을 수 있습니까? ?
이것은 어리석은 질문일 수도 있지만 저는 커널과 그 개념을 완전히 처음 접했고 나에게 도움이 될 만한 답을 찾지 못했습니다.
기록상으로 저는 Ubuntu 22, 커널 5.15.0-52-generic을 사용하고 있습니다.
답변1
기호는 ffffffffc04d7000
커널 메모리의 가상 주소에 저장되며(레이아웃 무작위화를 무시하지만 궁극적으로는 중요하지 않음) 사용자 공간에서 액세스할 수 없습니다.
사용자 공간에서 변수에 액세스할 수 있게(읽기 전용)하려면 vDSO를 통해 사용할 수 있도록 설정해야 합니다.gettimeofday
구현되었습니다. 당신은 또한 볼 수 있습니다vvar.h에서 새 변수를 선언하는 방법 Linux에서 vdso 만들기 |.