20150226

1. 영어 기사 읽기
1) Fishes’ Lateral Lines Sense Pressure and Predators, Scientific American
– They avoid obstacles, effortlessly slalom between vortices or whirlpools, and hide from predators (slalom – 활강 경기, vortex – 소용돌이)
– Nearly all fish, they say, have a similar network of sensors along their bodies that are exquisitely sensitive to changes in water pressure. (exquisitely – 정교하게)
2) FBI: Three men attempted to join ISIS, CNN
– An FBI intelligence bulletin to state and local law enforcement urged officers to be vigilant for not only recruits, but people who may want to carry out attacks. (vigilant – 바짝 경계하는)
– On February 2, Saidakhmetov brazenly appeared at the Department of Homeland Security offices in Manhattan and filled out an application for a travel document and had his photograph and fingerprints taken, the complaint said. (brazenly – 뻔뻔하게)


2. 실험 환경 구축
프로세스별 CR3 레지스터 값을 알아야 한다. CR3 레지스터 값을 읽어내는 시스템 콜을 추가하고, Pin을 사용해 실행 중인 프로세스를 DBI해, CR3 레지스터 값을 읽어내면 될 것 같다. 아니다. 생각해보니 Pin은 Pin 프로세스가 실행되는 것이므로, CR3 레지스터 값을 읽으면 Pin의 CR3 레지스터 값을 반환할 것이다.
gdb로 프로세스에 attach해서 system call을 실행하는 방법으로 할 수 있을 것 같다.

$gdb app `pidof app`
(gdb) call syscall(read_cr3)

다음 링크에서 아이디어를 얻음.
(Gregory Shpitalnik, Code Injection into Running Linux Application, http://www.codeproject.com/Articles/33340/Code-Injection-into-Running-Linux-Application)

다음은 CR3 레지스터의 값을 읽어내는 시스템 콜 함수이다.

#include <asm/processor.h>
#include <linux/kernel.h>
asmlinkage long sys_gumdaeng_syscall(void)
{
    unsigned long cr3 = 0L; 
    cr3 = read_cr3();
    printk(KERN_DEFAULT "CR3: %016lx\n", cr3);
}

아래의 쉘 스크립트로 원하는 어플리케이션의 CR3 레지스터 값을 알아낼 수 있다. 실제로 테스트해보았더니 잘 되었다. 이제는 이것을 스크립트로 만들어야 한다. 체크포인트 생성 스크립트는 내일 만들어야겠다.

pid=`pidof process_name`
sudo dmesg -c
rm file
printf "attach $pid\r\ncall syscall(314)\r\nq" > file
sudo gdb -q -x file; MSG=`dmesg`
echo $MSG

3. MARSS 디버깅
2015/01/14에 rip를 0으로 만들면서 비정상적으로 종료한다고 판단했었다. 하지만 그 주변 코드에서 rip를 출력해보니 rip가 0이 되는 경우가 종종 있었다. 오히려 문제가 되는 것은 원래 에러 발생의 원인인 physreg->data가 0의 값을 갖는 것이다. ReorderBufferEntry::commit()의 assert(physreg->data);에서 0의 값을 갖는 경우는 에러가 발생하는 경우 외에는 없었다. 한편, ReorderBufferEntry::commit() 함수의 시작 지점과 에러 발생 지점까지의 physreg->data의 값은 동일하다. (에러 발생 지점의 physreg->data의 값은 반드시 함수 시작 지점과 같다.)

에러 발생시의 call stack은 다음과 같으며, 거꾸로 따라가보면 physreg->data가 0이 되는 시점을 알 수 있을 듯 하다.

(gdb) bt
#0  0x00007ffff4c91cc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007ffff4c950d8 in __GI_abort () at abort.c:89
#2  0x00007ffff4c8ab86 in __assert_fail_base (fmt=0x7ffff4ddc3d0 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", 
    assertion=assertion@entry=0x8f2582 "physreg->data", file=file@entry=0x8f1f10 "ptlsim/build/core/ooo-core/ooo-pipe.cpp", line=line@entry=2119, 
    function=function@entry=0x8f3780 <ooo::ReorderBufferEntry::commit()::__PRETTY_FUNCTION__> "int ooo::ReorderBufferEntry::commit()") at assert.c:92
#3  0x00007ffff4c8ac32 in __GI___assert_fail (assertion=0x8f2582 "physreg->data", file=0x8f1f10 "ptlsim/build/core/ooo-core/ooo-pipe.cpp", line=2119, 
    function=0x8f3780 <ooo::ReorderBufferEntry::commit()::__PRETTY_FUNCTION__> "int ooo::ReorderBufferEntry::commit()") at assert.c:101
#4  0x000000000062c181 in ooo::ReorderBufferEntry::commit (this=0x3238688) at ptlsim/build/core/ooo-core/ooo-pipe.cpp:2119
#5  0x000000000062a5ea in ooo::ThreadContext::commit (this=0x32349b0) at ptlsim/build/core/ooo-core/ooo-pipe.cpp:1614
#6  0x00000000006333cc in ooo::OooCore::runcycle (this=0x321f1b0, none=0x0) at ptlsim/build/core/ooo-core/ooo.cpp:649
#7  0x0000000000643d3d in superstl::TFunctor1<ooo::OooCore>::operator() (this=0x32348d0, arg=0x0) at ptlsim/lib/superstl.h:3950
#8  0x00000000006b3746 in superstl::Signal::emit (this=0x3230b90, arg=0x0) at ptlsim/build/lib/superstl.cpp:1431
#9  0x000000000072a42b in BaseMachine::run (this=0x142cf40 <coremodel>, config=...) at ptlsim/build/sim/machine.cpp:265
#10 0x000000000073ea87 in ptl_simulate () at ptlsim/build/sim/ptlsim.cpp:1365
#11 0x00000000005c6fd3 in sim_cpu_exec () at qemu/cpu-exec.c:310
#12 0x0000000000424e3f in main_loop () at qemu/vl.c:1450
#13 0x0000000000428c04 in main (argc=13, argv=0x7fffffffe5d8, envp=0x7fffffffe648) at qemu/vl.c:3189

ROB에 값을 넣는 경우를 잘 봐야 할 듯 하다. commit에서는 ROB에 이미 들어가있는 값을 commit하기만 한다. ThreadContext 구조체의 함수 호출 순서는 다음과 같다. (2015/01/15)

ThreadContext::commit
ThreadContext::writeback
ThreadContext::transfer
ThreadContext::tlbwalk
ThreadContext::complete
ThreadContext::dispatch
ThreadContext::frontend
ThreadContext::rename
ThreadContext::fetch

이를 고려해 에러 발생 지점을 확인하고 있는 중.


4. System Call 추가
커널의 정보를 확인해야 하는데, 해당 정보를 받아오는 것은 리눅스 커널에 구현되어 있지 않음. 창현이 형이 시스템 콜을 추가해 정보를 받아오는 방법이 있다고 알려주셨다. 아래 두 블로그를 참고해 간단한 system call을 구현해 봄. [1]에서 system call 추가 방법을 확인하고, [2]의 예제를 따라함.
[1] 박창현, Adding a System call for Linux 3.10 x86_64, http://heartinpiece.blogspot.kr/2014/01/adding-system-call-for-linux-310-x8664.html
[2] 리눅스 시스템 콜 추가, http://harryp.tistory.com/69

Advertisements
Tagged with: , , , , , , , , , , , ,
Posted in 1) Memo

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

누적 방문자 수
  • 96,354 hits
%d bloggers like this: