functions - みる会図書館


検索対象: Surreptitious Software
320件見つかりました。

1. Surreptitious Software

154 Program Analysis Another technique is to びる走戸 0 / 〃 / the program (write program state, such as modi- fied pages and open 石 le descriptors) to disk at fixed intervals. Unfortunately, reverse execution doesn t seem tO have made it intO any mainstream debuggers. Here, we re going to show you one particularly clever combination of tech- mques for implementlng an efficient (for the programmer) reverse debugger. Algo- rithm REBB [ 46 ] is び 0 ″〃た房必 i. e. , it establishes a timeline of the execution by lncrementing a variable step—cnt for every source COde line executed. You d0 this by annotating the program with calls tO a function step ( ) before every source code line. For certain debugging operations, you also need to keep track of the depth of the call stack. You do this by adding calls to the functions enter ( ) and leave ( ) at the beginnmg and end of every function. They increment and decrement a counter call-depth. Here are the definitions Of step, enter, and leave: step—cnt 十十 ; void step() { long sc-stop-val long step—cnt sc-stop-val) if (step-cnt i nt VOid VOid 〃叩 / 0 / 厖ノ訪 4 e お call-depth = ① ; enter() {call-depth + + ; } leave() {call-depth- typedef void い Oper) ( ) ; {&step ,&step ,&step , ・ Oper STEP [ ] tations ()n light gray) have been added: And here's what the modular exponentiation routine 100kS like after the anno-

2. Surreptitious Software

1 う 3 Reconst1tuting Source function foo body while return cond bOdy v 0 i d fo 0 ( ) { while ( x く 1 ① ) i f ( x く 5 ) X 十十 ; e 1 S e x + = 2 ; printf(); rig ht 1 a 「 X const C O X ↑・ if-else れ right cond ca right left printf 10 a 「 X const C O X - す・ right left right const 2 var X a 「 X a 「 X const 5 Figure 5.5 Decompilation example, continued from Figure 引 4 第・ 182 statements. The AST has one node type for every kind Of statement and operator ⅲ the target language. Once the AST has been built, generating source code is therefore trivial. Figure う . う shows the AST and the C source corresponding t0 the simplified control flow graph in Figure 引 4 第 , 182. 53.2.1 AIgorithm RECG. ・ Recovering High-Level control 日 ow Cristina Cifuentes'5 decompilation algorithm RECG [ 72 ] (Algorithm ろ 3 ) makes use of a database Of ゞな〃 4 / ″尾 Of library functions generated automatically from different compilers. This allows the decompiler t0 discard functions that the compiler in- serted and replace calls t0 them with 叩 propriate symbolic names. The algorithm uses several data flOW analyses. For example, it uses a 尾 4 びる g ノに〃″あ〃ゞ data flOW analysis (Section う .1.2 第 127 ) tO determine which instructions set the condition codes that are later tested by conditional branch instructions. Here, the use-definition chains in instructions う and 6 indicate that the zero (ZF) and sign (SF) flags that 5. AKA the "Queen of Decompilation.

3. Surreptitious Software

6.2 Moving Code Around 379 To illustrate this, suppose you want to obfuscate a program that contains t , 0 functions, and ゐ . They have the following code-bytes: 0 10 う 20 4 99 At obfuscation time, Algorithm OBFMAMDSB would replace and ゐ with the template T and tWO edit scripts の and の : C 9- っ ) O フ一 0 1 2 ろ一 0 1 フっ ) -4 [ 1 →う , 2 → 6 ] は→ 9 , 2 →引 The template contains those code-bytes that / 1 and ゐ have in common. ln the locations where and ゐ differ (indicated above by question marks), you can put whatever you want—the more confusing for an attacker the better. At runtime, the first time the program wants to execute it must first patch T using 臼 , replacing the code-byte at offset 1 with う and the code-byte at offset 2 with 6. If there's a subsequent call to (without an intervening call to ゐ ) , you can dispense with the editing and jump directly to 7 '. When the program calls ゐ , on the other hand, it must first modify T using the edit script の . ln this way, the T memory region will constantly change, first contaimng an incomplete function and then alternating between containing the code-bytes for / 1 and み . Algorithm 63 づ 80 contains an overvrew of this technique. The first step is to decide which functions should be in the same ツ / i. e. , which should reside in the same template at runtime. If your code 100kS like this main() { while(l) {

4. Surreptitious Software

362 6.2 Moving Code Around Dynamic Obfuscation All algorithms in this chapter produce self-modifying programs. At best, this will have serlous performance implications; at worst, it will reqture you to insert highly unstealthy instructlons to make sure that the newly modified code gets executed rather than the code that is currently in caches and in the instruction pipeline. On the X86 architecture, the processor will do the right thing without any specific help from the programmer. On the PowerPC architecture, however, before you jump to a modified COde segment, you have to issue the following four instructions ()@ is a register containing the address Of the modified instruction): dcbst ① .r@ sync icbi ① , r ① 1sync / / make sure the data cache line is written to memory / / make sure that the last instruction completed / / invalidate the instruction cache line / / clear the instruction pipeline These instructions are highly unusual in normal code and will serve as an easy target for an adversary,. An additional issue is that the code pages you modify must be both writable and executable. Depending on your operating system, this will be more or less easy, and stealthy, to arrange. On Linux, for example, you need to use the mprotect system call to set the write bit for any page you intend to modify. See Listing 6.1 》づ 6 ろ . The algorithms in this section "move code around" to make it difficult to analyze. Algorithm 0BFKMNM is the most straightforward of them all: lt overwrites an lnstruction with a bogus one and then replaces the bogus instruction with the original before it gets executed. As you will see, lt's not hard to attack using a debugger or emulator. Algorithm OBFAGswap divides a function into chunks and, as execution proceeds, cyclically swaps cells with each other. Algorithm 0BFMAMDSB finally, arranges the code so that several functions are merged so that they "share" the same location. At runtime, the location is patched to contain the function that needs tO execute next, ln essence making functions move ln and out Of the location. 6.2.1 AIgorithm 0 卲ⅢⅣ M. : Replacing lnstructions The first algorithm we're going to show you, AIgorithm 0BFKMNM [ 189 ー 191 ] , simply replaces instructions with bogus ones. At some point in the execution, before the bogus lnstructlon is about to execute, update code restores the instruction back

5. Surreptitious Software

746 static analysis ( co 厩 / 〃″にノ ) data dependence analysis , 132— data flow analysis, 127 ーリ 2 described, 118 ー 119 slicing, 141 ー 145 Static fingerprints, 40 strong obfuscating transformatiom defined' 306 disassembly of, 172 ー 174 advantages 0f, 172 Stripped binaries, 6 ) , stored measurement list (SML), 675 Stirmark, 470 , 495 Steganography, 5 defined , 224 Steganographic stealth , 22 ろ systems for, う 22 goals of, う 22 algorithms for, う 2 う 26 Steganographic embeddings , 468 of watermark, う 05 ー 516 , 561 steganographic, 22 去 224 local, 225 described , 224 Stealth, 222 ー 2 幻 static path feasibility analysis , 244 defined, 405 Tamperproofing , xv, XVI Tamperproof module, 672 XBOX, 69 う 97 Smartcards, 701 ー 708 IBM 4758 , 708 ー 711 698 ー 700 Dallas Semiconductor DS50002 FB , 69 う 96 , Tamperproof devices responding t0 , 410 defined, 40 う checking for, 4 710 Tam penng military use Of, xviii—xxi attack model and , い 7 surreptitious SOftW ・ are lmportance Of, XVi—XX11 function Of, xvi surreptitious software, XV Superoperato rs , 207 Sun . Microsystems , XVIII Subtractive attacks , 484 Substitution, 105 Style metrics, 190 , 191 ー 19 lndex desc ribed, 52 example of, 6 of execution paths, う 92 ー 598 functions in , 404 ー 405 obfuscation as adjunct t0, 401 related to watermarking, 402 , 494 ー 498 remote, う 4 , う 47 , 4 ( ) 4 ー 405 system design for, 411712 , 425727 uses of, ーめ , 4 ( ) 2 ー 404 , 4 of watermarking widgets, 580 ー 581 Tamper-resistant watermarks , 469 TEA (Tiny Encryption Algorithm), 79 ー 80 Testing functions, 412 Text, watermarking of, 475778 ・新 a に s Group, xix, う 16 Threat model, developing, め T1ming attacks, 70 & ー 707 TPCA algorithm, 414 , 417718 advantages of, 459 example of, 416717 overview of, 415 FIVCNS algorithm , 462764 "ITCVCPSJ algorithm , 447750 "IVGCK algorithm , 4 ろ 87 う 9 'ITHMST 引 go rithm , 42 724 advantages of, 4 9 corrector slot values, 4307 引 example of, 428 ー 429 interval construction ⅲ , 427 ・ 728 overview of, 424 and system design, 425727 TPJJV algorithm , 4 う 07 'ITSLSPDK algorithm, 459760 uses of, 460762 "ITTCJ algorithm, 44 ( ) 744 overview of, 442 'IVZG algorithm , 455759 , 465 overview of, 456 Tracing, 16 ろ algorithm for, 165 ー 168 Transformation stage, 7 Translation, 101 , 1 の Tree-based analysis, 6 引ーめ Treemap views, defined, 197 ー 198 Trusted platform module (TPM), 6 必 applications of, 682 め authenticated boot based on, 670 ー 67 ろ challenging of, 677 ー 679 components of, 676 controversies regarding , 681 ーる 8 う function of, 657 , 67 ( ) ー 671

6. Surreptitious Software

70 Methods of Attack an d Defense ⅲ a license check), then this may not be t00 much of a problem. Modifications with more wide-ranging effects are harder to check when the attacker has no deep knowledge of the internals of the program, and no test sulte to run to convince him that his changes didn't break the program in some subtle way. Software protection algorithms have been designed to hamper the attacker in each of the locate-alter-test phases of the attack cycle. For example, to make the program harder tO alter, you can make many portlons Of it interdependent, SO that 10Ca1 changes are not enough to disable the protection code. You can S10 从み down the locate phase by making the program appear to execute non-deterministically, choosing different paths through the program every tlme it's run. Finally, you can add bogus execution paths to the program so that an attacker has to build many test cases in order tO convince himself that the changes he's made have no Ⅲ effects. 2.1.4.2 Dynamic AnaIysis—Exploiting Cracks in the Black Box Earlier we noted that even a statically linked stripped binary executable will leak information. At the very least, the main entry point is known, which makes it possible for the attacker to start to learn about the program by the (likely laborious) task of single-stepping through it. A common attack strategy is tO try tO link the external behavior of the program t0 its internal behavior by watching system calls and calls to library functions. For example, the first trivial attack a cracker whO's trying tO remove a license check will try is t0 locate the call t0 the pop-up box that delivers the "Please enter your program activation code" message. ln Windows he could, for example, set a breakpoint on the GetDIgItemInt ( ) library function that translates the number entered ⅲ the dialog box into an integer value. When the breakpoint hits, he can 100k up the call stack to find the location of the user code that called the function. Most likely, this will be ⅲ the vicinity of the code that checks if the activation code is valid. If the program is statically linked and stripped, finding library functions by name is no longer possible. System calls, however, provide a reliable interface to the operatmg system, and attackers can use them tO find the location of common library functions. lt's safe tO assume, for example, that printf is golng tO invoke the write system call at some point. SO the attacker can simply set a breakpoint on write and, when the breakpoint hits, 100k up the call stack to find the location of what's likely tO be printf. 2.1.43 Static Analysis Static analysis can be done on severallevels. Some crackers are well versed in reading raw binary machine code and, most, certainly, read X86 assembly code as if it were their mother tongue. Thus, they requlre nothing more

7. Surreptitious Software

508 Software Watermarking point, and branches ル″る a methOd are restricted bY what the Java verifier can analyze. Problem 8.7 lt would be interestlng t0 examme some Microsoft programs t0100k for evidence that WMVVS is being used in practice. Before attempting consult a (good) lawyer t0 make sure you are not violating the DMCA or any 0ther pertlnent laws ln your Jurisdiction. 8.7.2.1 Embedding The WMVVS embedding routine has four main stages: 1. Encode the watermark integer Ⅳ as a graph G. 2. Turn G into a control flow graph C. 5. Add C to the original program P. 4. Tie C to p by adding bogus control flow edges. Real functions in real programs are typically small. A preliminary step is therefore t0 break up any large watermark integer intO a set Of smaller numbers {W()' ... , 社 ) 走ー 1 } , each Of which can then be encoded intO reasonably sized functions. The goal ofthe embedding is t0 produce, from each watermark piece 助 , a func- tion 第 that encodes that piece. we've already seen two ways 0f doing this: WMDM permutes the linearization 0f the function's basic blockS' and wMMIMIT selects new arithmetic lnstructlons. Here, we re gomg tO use a different namelY' tO convert wtinto a control flow graph whose 立母″尾 embeds the graph. Embedding watermarks as graphs is an idea you will see agam in the next chapter on watermarking, in section 9.1 ・ 546. ln section 8.10 5 , you will see several differ- ent kinds 0f gr 叩 h encodings. 嶬 call the functions that convert between graphs and watermark integers 叩る 0 い . The RPG graphs 0f Section 8.10.5 ト男 6 are particularly well suited for this algorithm. If you care about the stealth Of the watermark functiom you have tO consider the structure of the CFG very carefully. ln addition to being a な ga / CFG' you want it to be a e CFG. This means that the following conditions must hold: 1. The basic blocks should have out-degree of one or two, since that's what the translation Of normal control structures like if- and while- statements result in.

8. Surreptitious Software

204 Code Obfuscation typically optlmize for the sequence of instrucuons that is the shortest or will execute the fastest, but there's nothing stopping you from optrmizing for confusion instead ! C01 Ⅱ 1 on compiler code generation tricks can generate obfuscated code. For ex- ample, multiplication by a constant is often turned into a sequence of less obvious adds and shifts: y x ☆ 42 ; y = x くく 5 ; y + = x くく 3 ; y + = x くく 1 ; 4.1.1.2 AIgorithm OBFCFrecorder: Reordering Code and Data programmers tend tO put related pieces Of code close together, and compilers tend to lay out code ⅲ the order in which it occurs in the source code. Locality can therefore be an lmportant clue tO a reverse englneer as tO what pieces of code belong together. lt's therefore a good idea to randomize the placement of modules within a program, functions within a module, statements within a function, and instructlons within a statement. You can almost always trivially reorder modules and functions, but you can only reorder statements and instructions for as long as you don't violate any de- pendencies. A code obfuscation t001 that wants to reorder instructions needs to start by building a data- and control-dependence graph (Section う .1. 分 1 ろ 2 ). Two lnstructlons can be reordered if there are no dependencies between them. ln type-safe languages like Java, variable declarations that appear within the same scope can trivially be reordered. ln C, where programmers can play tricks with pointer arithmetic, and arrays are indexed without bounds checks, reorder- lng is much harder. ln this example, the programmer might not have intended to index outside the bounds of a, but he did anyway, and somehow his program still worked : int main() { int a[5]; int b[6] ; a[5]

9. Surreptitious Software

274 Code Obfuscation 4.5.4.2 Algorithm OBF ロ 1 。… ) , : Array Restructuring Like other data types, arrays can be split up intO pieces and the pieces can be scattered throughout the program. Also, the elements from several arrays of the same element type can be interleaved and merged intO one array. Additionally, since arrays come ⅲ multiple dimenslons, an n-dimensional array can be flattened into an array of 〃ー 1 dimensions or folded into one with 〃 + 1 dimensions. Algorithm OBFCTJarray [ 87 88 , 91 , 11 刀 provides such transformatlons. The 4 な 4 ア splitting transformation splits an array ス oflength 〃 into two arrays, B() and お 1 oflengths 0 and 1 , respectively. Formally [ 11 刀 , you need a function 化な that determines the array into which each element should go, and two functions, 戸 0 and 1 , which give the location of each element in the new arrays: e ん [ 0... 〃 ) → [0, 1 ] Then you get the following mapping between elements of ス and elements of お 0 and お 1 : Here's an example where we split array A into two arrays B and c so that the even-indexed elements go in B and the odd-indexed go in ( : 0 1 2 ろ 4 8 9 A: 1 2 ろ 4 う 6 7 8 9 10 0 1 2 4 C: 2 4 6 8 10 Any Other appropriate split function is, of course, possible. Here's what this trans- formation would look like ⅲ code: int A[] A[I] int i , sum=@ ; for ( i = ① ; i く 1 ① , 1 ① ; sum + = A[i] ; = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , ・ i 十十 ) 1 ① } ; int B ロ = { 1 , 3 , 5 , 7 , 9 } ; = { 2 , 4 , 6 , 8 , 1 ① } ; int C ロ int* E(int al[],int a2 ロ ,int i){ if ( ( i % 2 ) = = の return &(a1[i/2]) ; else 1 ① ; for(i=@; i く 1 ① ; i + + ) int i , sum=@ ; return &()2 [i/2] ) ;

10. Surreptitious Software

700 H ardware for Protecting S0ftware when he might have found it: lt should make something appear on the parallel port ! Moreover, every unique byte XX he tries tO write with the MOV instruction should result ⅲ a unique byte appearrng on the output port. SO the search is very simple: for ( x = ① ; x く 2 5 6 ; x + + ) n e X t y : for ( y = ① ; y く 2 5 6 ; y + + ) E2 ←① for ( z = ① ; z く 2 5 6 ; z + + ) r e s e t ( P U a n d fe e d i t t h e c 0 d e ①十① : X . + 1 : Y 0 ①十 2 : z ← -value read from port P2 if (E2(p) is not empty) goto nexty E2 ← E21J { p → return (x,y,E2) This code tries every possible value (x , y) for the first tWO bytes Of the instruction and tabulates all the values that appear on the P2 port in a set E2 when varymg the third byte through all values 0...2 . If 砠 256 bytes 叩 pear, then (x , y) is probably the MOV instruction. At the end Of this test, the attacker has collected the following information: E2 ゆ ) ア K , 40 + 1 K 。 0 + 2 ゆ ) , V() 5 2 5 2 He's certainly 0 任 to a good start, since he has 0 戸な knowledge 0f the encrypuon function for the byte at address 勾 + 2 ! ln the next step, he'll want t0 similarly deduce the encryption functions for . He can do this by address 40 + を 40 + 4 , and so on, which we call E3 E4 searching for a Nop-like instruction, which he can insert right before effectively moving it forward by one byte in the instructlon stream. Once he has tabulated a few encryption functions, seven is enough for the DS5()()2FP he knows eno ugh tO generate a small p rogram th at traverses memo ry and writes the contents of each decrypted byte t0 an output port. Markus Kuhn's attack is possible because 0f the small ciphertext granularity. An upgraded version 0f the DS5()()2FP, the DS う 24 Ⅳ DS う 2 う () , encrypts 8 bytes 0f data at a tlme rather than one byte at a time. This makes it much more costly tO tabulate the encryption functions.