
LIBVMCU는 AVR 마이크로 컨트롤러 바이너리의 정적 및 동적 분석을위한 작은 엔진입니다.
원시 데이터의 준비를 처리하고 다른 프로그램에서 추가로 처리 할 수 있습니다. 여기서 목표는 AVR 소스 코드와 프로그래밍 방식으로 상호 작용할 수 있도록하는 것입니다.
libvmcu가 당신에게 제공합니다
참고 :이 라이브러리는 여전히 개발 중입니다.
나는 예입니다
II 쇼케이스
III 설정 vmcu
IV 지원 MCU
v 동적 분석
VI 정적 분석
VII 명령 세트
VIII 바인딩
IX 기여
X 크레딧
XI 문서
/* A possible implementation of print_instruction can be found below */
int main ( const int argc , const char * * argv ) {
/* ignoring checks for this example */
vmcu_model_t * m328p = vmcu_model_ctor ( VMCU_DEVICE_M328P );
vmcu_report_t * report = vmcu_analyze_file ( "file.hex" , m328p );
for ( uint32_t i = 0 ; i < report -> cfg -> used ; i ++ ) {
vmcu_cfg_node_t * node = & report -> cfg -> node [ i ];
print_instruction ( node -> xto . i );
if ( node -> t != NULL ) {
printf ( "true -> " );
print_instruction ( node -> t -> xto . i );
}
if ( node -> f != NULL ) {
printf ( "false -> " );
print_instruction ( node -> f -> xto . i );
}
printf ( "n" );
}
vmcu_report_dtor ( report );
vmcu_model_dtor ( m328p );
return EXIT_SUCCESS ;
} 0x0000 .... f1f3 breq - 2 ; (ZF == 1): PC <- PC + -2 + 1
true - > 0x3fff .... 839a sbi 0x10 , 3 ; IO[0x10, 3] <- 1
false - > 0x0001 .... 0fef ldi r16 , 0xff ; r16 <- 0xff
--------------------------------------------------------------------------------
0x0001 .... 0fef ldi r16 , 0xff ; r16 <- 0xff
true - > 0x0002 .... 5817 cp r21 , r24 ; r21 - r24
--------------------------------------------------------------------------------
0x0002 .... 5817 cp r21 , r24 ; r21 - r24
true - > 0x0003 .... 19f4 brne 3 ; (ZF == 0): PC <- PC + 3 + 1
--------------------------------------------------------------------------------
0x0003 .... 19f4 brne 3 ; (ZF == 0): PC <- PC + 3 + 1
true - > 0x0007 .... 0127 eor r16 , r17 ; r16 <- r16 ^ r17
false - > 0x0004 .... a895 wdr ; watchdog reset
--------------------------------------------------------------------------------
0x0004 .... a895 wdr ; watchdog reset
true - > 0x0005 .... 8895 sleep ; circuit sleep
--------------------------------------------------------------------------------
0x0005 .... 8895 sleep ; circuit sleep
true - > 0x0006 .... 0000 nop ; no operation
--------------------------------------------------------------------------------
0x0006 .... 0000 nop ; no operation
true - > 0x0007 .... 0127 eor r16 , r17 ; r16 <- r16 ^ r17
--------------------------------------------------------------------------------
0x0007 .... 0127 eor r16 , r17 ; r16 <- r16 ^ r17
--------------------------------------------------------------------------------
0x3fff .... 839a sbi 0x10 , 3 ; IO[0x10, 3] <- 1
true - > 0x0000 .... f1f3 breq - 2 ; (ZF == 1): PC <- PC + -2 + 1
-------------------------------------------------------------------------------- /* A possible implementation of print_instruction can be found below */
int main ( const int argc , const char * * argv ) {
/* ignoring checks for this example */
vmcu_model_t * m328p = vmcu_model_ctor ( VMCU_DEVICE_M328P );
vmcu_report_t * report = vmcu_analyze_file ( "file.srec" , m328p );
for ( uint32_t i = 0 ; i < report -> progsize ; i ++ ) {
printf ( "0x%04x " , report -> disassembly [ i ]. addr );
print_instruction ( & report -> disassembly [ i ]);
}
vmcu_report_dtor ( report );
vmcu_model_dtor ( m328p );
return EXIT_SUCCESS ;
} 0x004e ldi r27 , 0x06 ; r27 <- 0x06
0x004f rjmp 1 ; PC <- PC + 1 + 1
0x0050 st X +, r1 ; DS[X+] <- r1
0x0051 cpi r26 , 0x20 ; r26 - 0x20
0x0052 cpc r27 , r18 ; r27 - r18 - CF
0x0053 brne - 4 ; (ZF == 0): PC <- PC + -4 + 1
0x0054 call 0x60b ; PC <- 0x60b /* A possible implementation of print_instruction can be found below */
int main ( const int argc , const char * * argv ) {
/* ignoring checks for this example */
vmcu_model_t * m328p = vmcu_model_ctor ( VMCU_DEVICE_M328P );
vmcu_report_t * report = vmcu_analyze_file ( "file.hex" , m328p );
for ( uint32_t i = 0 ; i < report -> progsize ; i ++ ) {
vmcu_instr_t * instr = & report -> disassembly [ i ];
if ( instr -> writes . c_flag == true)
print_instruction ( instr );
if ( instr -> reads . c_flag == true)
print_instruction ( instr );
}
vmcu_report_dtor ( report );
vmcu_model_dtor ( m328p );
return EXIT_SUCCESS ;
} subi r18 , 0x00 ; r18 <- r18 - 0x00
adiw r29:r28 , 0x1a ; r29:r28 <- r29:r28 + 0x1a
sbci r23 , 0xff ; r23 <- r23 - 0xff - CF
cpc r19 , r17 ; r19 - r17 - CF int main ( const int argc , const char * * argv ) {
/* ignoring checks for this example */
vmcu_model_t * m328p = vmcu_model_ctor ( VMCU_DEVICE_M328P );
vmcu_report_t * report = vmcu_analyze_file ( "file.hex" , m328p );
for ( uint32_t i = 0 ; i < report -> n_vector ; i ++ ) {
vmcu_vector_t * vect = & report -> vector [ i ];
vmcu_instr_t * isr = vect -> xto -> i ;
printf ( "Vector ID %d @ 0x%04xn" , vect -> id , vect -> addr );
printf ( " interrupt service routine at 0x%04x" , isr -> addr );
printf ( "nn" );
}
vmcu_report_dtor ( report );
vmcu_model_dtor ( m328p );
return EXIT_SUCCESS ;
} Vector ID 16 @ 0x0020
interrupt service routine at 0x03f5
Vector ID 17 @ 0x0022
interrupt service routine at 0x008a
Vector ID 18 @ 0x0024
interrupt service routine at 0x03c3
Vector ID 19 @ 0x0026
interrupt service routine at 0x039d /* A possible implementation of print_instruction can be found below */
int main ( const int argc , const char * * argv ) {
/* ignoring checks for this example */
vmcu_model_t * m328p = vmcu_model_ctor ( VMCU_DEVICE_M328P );
vmcu_report_t * report = vmcu_analyze_file ( "file.hex" , m328p );
for ( uint32_t i = 0 ; i < report -> n_label ; i ++ ) {
vmcu_label_t * lx = & report -> label [ i ];
printf ( "0x%04xtL%dnn" , lx -> addr , lx -> id );
for ( uint32_t j = 0 ; j < lx -> n_xfrom ; j ++ ) {
vmcu_xref_t * x = & lx -> xfrom [ j ];
printf ( " xref from 0x%04x " , x -> i -> addr );
print_instruction ( x -> i );
}
printf ( "n" );
}
vmcu_report_dtor ( report );
vmcu_model_dtor ( m328p );
return EXIT_SUCCESS ;
} 0x04c6 L75
xref from 0x04a1 call + 1222 ; PC <- 0x4c6
xref from 0x0a84 call + 1222 ; PC <- 0x4c6
xref from 0x0b5c call + 1222 ; PC <- 0x4c6
0x04e2 L76
xref from 0x05d4 rjmp - 243 ; PC <- PC - 0xf3 + 1
0x05d0 L77
xref from 0x04e1 rjmp + 238 ; PC <- PC + 0xee + 1 /* A possible implementation of print_instruction can be found below */
int main ( const int argc , const char * * argv ) {
/* ignoring checks for this example */
vmcu_model_t * m328p = vmcu_model_ctor ( VMCU_DEVICE_M328P );
vmcu_report_t * report = vmcu_analyze_file ( "file.hex" , m328p );
for ( uint32_t i = 0 ; i < report -> n_sfr ; i ++ ) {
vmcu_sfr_t * sfr = & report -> sfr [ i ];
printf ( "SFR ID: %dnn" , sfr -> id );
for ( uint32_t j = 0 ; j < sfr -> n_xfrom ; j ++ ) {
vmcu_xref_t * x = & sfr -> xfrom [ j ];
printf ( " xref from 0x%04x " , x -> i -> addr );
print_instruction ( x -> i );
}
printf ( "n" );
}
vmcu_report_dtor ( report );
vmcu_model_dtor ( m328p );
return EXIT_SUCCESS ;
} SFR ID: 17
xref from 0x00f4 sbi 0x1f , 2 ; IO[1f, 2] <- 0x01
xref from 0x00f5 sbi 0x1f , 1 ; IO[1f, 1] <- 0x01
SFR ID: 50
xref from 0x004c sts 0x006e , r1 ; DATA[0x6e] <- R1
xref from 0x0051 lds r24 , 0x006e ; R24 <- DATA[0x6e]
xref from 0x0054 sts 0x006e , r24 ; DATA[0x6e] <- R24 /* 0x6a97 (little endian) <=> sbiw r29:r28, 0x1a */
int main ( const int argc , const char * * argv ) {
/* initialize a device model */
vmcu_model_t * m328p = vmcu_model_ctor ( VMCU_DEVICE_M328P );
vmcu_instr_t instr ;
vmcu_disassemble_bytes ( 0x6a97 , & instr , m328p );
const VMCU_IKEY key = instr . key ; // VMCU_IKEY_SBIW
const VMCU_GROUP grp = instr . group ; // VMCU_GROUP_MATH_LOGIC
const uint32_t opcode = instr . opcode ; // 0x976a (big endian)
const uint32_t addr = instr . addr ; // 0x0000 (undefined)
const bool dword = instr . dword ; // false
const bool exec = instr . exec ; // true
vmcu_operand_t * src = & instr . src ; // source operand
vmcu_operand_t * dest = & instr . dest ; // destination operand
VMCU_OPTYPE src_type = src -> type ; // VMCU_OPTYPE_K6
VMCU_OPTYPE dest_type = dest -> type ; // VMCU_OPTYPE_RP
const uint8_t src_val = src -> k ; // 0x1a
VMCU_REGISTER dest_rh = dest -> rp . high ; // VMCU_REGISTER_R29
VMCU_REGISTER dest_rl = dest -> rp . low ; // VMCU_REGISTER_R28
const bool writes_hf = instr . writes . h_flag ; // false
const bool writes_cf = instr . writes . c_flag ; // true
const bool reads_io = instr . reads . io ; // false
const bool reads_nf = instr . reads . n_flag ; // false
vmcu_mnemonic_t * mnem = & instr . mnem ; // instruction mnemonic
const char * base_str = mnem -> base ; // "sbiw"
const char * dest_str = mnem -> dest ; // "r29:r28"
const char * src_str = mnem -> src ; // "0x1a"
const char * com_str = mnem -> comment ; // "r29:r28 <- r29:r28 - 0x1a"
vmcu_model_dtor ( m328p );
return EXIT_SUCCESS ;
} /* this snippet can be used to assemble and print an instruction */
void print_instruction ( const vmcu_instr_t * instr ) {
printf ( "%s" , instr -> mnem . base );
if ( instr -> dest . type != VMCU_OPTYPE_NONE )
printf ( " %s," , instr -> mnem . dest );
if ( instr -> src . type != VMCU_OPTYPE_NONE )
printf ( " %s" , instr -> mnem . src );
printf ( " %sn" , instr -> mnem . comment );
}
libvmcu로 작성된 작은 디버거
현재이 라이브러리는 두 개의 헤더와 함께 제공되며 엔진/포함/libvmcu에서 모두 찾을 수 있습니다.
이 저장소의 최상위 레벨에 prog.c라는 파일이 있으며 libvmcu와 연결하려고합니다.
/* prog.c */
#include "libvmcu_analyzer.h"
#include "libvmcu_system.h"
int main ( void ) {
/* do something */
return 0 ;
} You@Terminal:~ $ cd build-release/
You@Terminal:~ $ make -f build.mk You@Terminal:~ $ gcc -Iengine/include/libvmcu/ -c prog.c -o prog.o You@Terminal:~ $ gcc -o prog prog.o -Lbuild-release/ -lvmcu -lm그게 다야. 문제에 직면하면 드라이버/ 디렉토리의 몇 가지 예를 살펴보십시오.
LIBVMCU는 정적 분석을 위해 가능한 많은 AVR 유형을 지원하려고합니다. 동적 분석은 현재 ATMEGA328 제품군에 대해서만 계획되어 있지만 향후 연장 될 수 있습니다.
정적 분석에 새로운 마이크로 컨트롤러를 추가하는 것은 매우 쉽습니다. 자세한 내용은 엔진/*/Arch/를 살펴보십시오.
AVR 장치 코어
Avre 장치 코어
AVRE+ 장치 코어
AVRXM 장치 코어
AVRXT 장치 코어
AVRRC 장치 코어
분리된다
크로스 참조 (xref-from, xref-to)
분석기 플래그
지침을 분해하고 분류하십시오
AVR 바이너리 분석기
형식 리더
인터럽트 지원
순환 정확한 실시간 시뮬레이션
133 AVR 어셈블리 지침 지원
내부 주변 장치의 정확한 시뮬레이션
현재 VMCU 지원 : ~ 133 지침. 몇 가지 몇 가지 지침이 'NOP'지침으로 구현되므로 실제 기능이 없습니다. 이 지침은 가능한 빨리 구현됩니다. 다음 지침에는 추가 작업이 필요합니다.
다른 모든 어셈블리 지침은 잘 작동합니다.
LIBVMCU는 기본 기능에 대한 Java 바인딩을 가지고 있습니다. 자세한 내용은 Bindings/Java/를 참조하십시오.
또한 바인딩이 엔진 개발로 인해 항상 최신 버전에서 작동하지는 않을 수 있습니다.
| 엔진 | 드라이버 | 바인딩 | 테스트 |
|---|---|---|---|
| PR에 대한 폐쇄 | 홍보를 위해 열립니다 | 홍보를 위해 열립니다 | 홍보를 위해 열립니다 |
이 글을 작성할 때까지 문서는 여전히 개발 중입니다. (불완전한) 문서는 https://github.com/milo-d/libvmcu-virtual-mcu-library/wiki에서 찾을 수 있습니다
정보가없고 위키를 기다리고 싶지 않은 경우 LIBVMCU 헤더 파일도 잘 문서화되어 있습니다.