This page has moved to a new address.

How to detect software tampering

body { background:#aba; margin:0; padding:20px 10px; text-align:center; font:x-small/1.5em "Trebuchet MS",Verdana,Arial,Sans-serif; color:#333; font-size/* */:/**/small; font-size: /**/small; } /* Page Structure ----------------------------------------------- */ /* The images which help create rounded corners depend on the following widths and measurements. If you want to change these measurements, the images will also need to change. */ @media all { #content { width:740px; margin:0 auto; text-align:left; } #main { width:485px; float:left; background:#fff url("") no-repeat left bottom; margin:15px 0 0; padding:0 0 10px; color:#000; font-size:97%; line-height:1.5em; } #main2 { float:left; width:100%; background:url("") no-repeat left top; padding:10px 0 0; } #main3 { background:url("") repeat-y; padding:0; } #sidebar { width:240px; float:right; margin:15px 0 0; font-size:97%; line-height:1.5em; } } @media handheld { #content { width:90%; } #main { width:100%; float:none; background:#fff; } #main2 { float:none; background:none; } #main3 { background:none; padding:0; } #sidebar { width:100%; float:none; } } /* Links ----------------------------------------------- */ a:link { color:#258; } a:visited { color:#666; } a:hover { color:#c63; } a img { border-width:0; } /* Blog Header ----------------------------------------------- */ @media all { #header { background:#456 url("") no-repeat left top; margin:0 0 0; padding:8px 0 0; color:#fff; } #header div { background:url("") no-repeat left bottom; padding:0 15px 8px; } } @media handheld { #header { background:#456; } #header div { background:none; } } #blog-title { margin:0; padding:10px 30px 5px; font-size:200%; line-height:1.2em; } #blog-title a { text-decoration:none; color:#fff; } #description { margin:0; padding:5px 30px 10px; font-size:94%; line-height:1.5em; } /* Posts ----------------------------------------------- */ .date-header { margin:0 28px 0 43px; font-size:85%; line-height:2em; text-transform:uppercase; letter-spacing:.2em; color:#357; } .post { margin:.3em 0 25px; padding:0 13px; border:1px dotted #bbb; border-width:1px 0; } .post-title { margin:0; font-size:135%; line-height:1.5em; background:url("") no-repeat 10px .5em; display:block; border:1px dotted #bbb; border-width:0 1px 1px; padding:2px 14px 2px 29px; color:#333; } a.title-link, .post-title strong { text-decoration:none; display:block; } a.title-link:hover { background-color:#ded; color:#000; } .post-body { border:1px dotted #bbb; border-width:0 1px 1px; border-bottom-color:#fff; padding:10px 14px 1px 29px; } html>body .post-body { border-bottom-width:0; } .post p { margin:0 0 .75em; } { background:#ded; margin:0; padding:2px 14px 2px 29px; border:1px dotted #bbb; border-width:1px; border-bottom:1px solid #eee; font-size:100%; line-height:1.5em; color:#666; text-align:right; } html>body { border-bottom-color:transparent; } em { display:block; float:left; text-align:left; font-style:normal; } a.comment-link { /* IE5.0/Win doesn't apply padding to inline elements, so we hide these two declarations from it */ background/* */:/**/url("") no-repeat 0 45%; padding-left:14px; } html>body a.comment-link { /* Respecified, for IE5/Mac's benefit */ background:url("") no-repeat 0 45%; padding-left:14px; } .post img { margin:0 0 5px 0; padding:4px; border:1px solid #ccc; } blockquote { margin:.75em 0; border:1px dotted #ccc; border-width:1px 0; padding:5px 15px; color:#666; } .post blockquote p { margin:.5em 0; } /* Comments ----------------------------------------------- */ #comments { margin:-25px 13px 0; border:1px dotted #ccc; border-width:0 1px 1px; padding:20px 0 15px 0; } #comments h4 { margin:0 0 10px; padding:0 14px 2px 29px; border-bottom:1px dotted #ccc; font-size:120%; line-height:1.4em; color:#333; } #comments-block { margin:0 15px 0 9px; } .comment-data { background:url("") no-repeat 2px .3em; margin:.5em 0; padding:0 0 0 20px; color:#666; } .comment-poster { font-weight:bold; } .comment-body { margin:0 0 1.25em; padding:0 0 0 20px; } .comment-body p { margin:0 0 .5em; } .comment-timestamp { margin:0 0 .5em; padding:0 0 .75em 20px; color:#666; } .comment-timestamp a:link { color:#666; } .deleted-comment { font-style:italic; color:gray; } .paging-control-container { float: right; margin: 0px 6px 0px 0px; font-size: 80%; } .unneeded-paging-control { visibility: hidden; } /* Profile ----------------------------------------------- */ @media all { #profile-container { background:#cdc url("") no-repeat left bottom; margin:0 0 15px; padding:0 0 10px; color:#345; } #profile-container h2 { background:url("") no-repeat left top; padding:10px 15px .2em; margin:0; border-width:0; font-size:115%; line-height:1.5em; color:#234; } } @media handheld { #profile-container { background:#cdc; } #profile-container h2 { background:none; } } .profile-datablock { margin:0 15px .5em; border-top:1px dotted #aba; padding-top:8px; } .profile-img {display:inline;} .profile-img img { float:left; margin:0 10px 5px 0; border:4px solid #fff; } .profile-data strong { display:block; } #profile-container p { margin:0 15px .5em; } #profile-container .profile-textblock { clear:left; } #profile-container a { color:#258; } .profile-link a { background:url("") no-repeat 0 .1em; padding-left:15px; font-weight:bold; } ul.profile-datablock { list-style-type:none; } /* Sidebar Boxes ----------------------------------------------- */ @media all { .box { background:#fff url("") no-repeat left top; margin:0 0 15px; padding:10px 0 0; color:#666; } .box2 { background:url("") no-repeat left bottom; padding:0 13px 8px; } } @media handheld { .box { background:#fff; } .box2 { background:none; } } .sidebar-title { margin:0; padding:0 0 .2em; border-bottom:1px dotted #9b9; font-size:115%; line-height:1.5em; color:#333; } .box ul { margin:.5em 0 1.25em; padding:0 0px; list-style:none; } .box ul li { background:url("") no-repeat 2px .25em; margin:0; padding:0 0 3px 16px; margin-bottom:3px; border-bottom:1px dotted #eee; line-height:1.4em; } .box p { margin:0 0 .6em; } /* Footer ----------------------------------------------- */ #footer { clear:both; margin:0; padding:15px 0 0; } @media all { #footer div { background:#456 url("") no-repeat left top; padding:8px 0 0; color:#fff; } #footer div div { background:url("") no-repeat left bottom; padding:0 15px 8px; } } @media handheld { #footer div { background:#456; } #footer div div { background:none; } } #footer hr {display:none;} #footer p {margin:0;} #footer a {color:#fff;} /* Feeds ----------------------------------------------- */ #blogfeeds { } #postfeeds { padding:0 15px 0; }

Tuesday, November 2, 2010

How to detect software tampering

The chapter below, from the book Surreptitious Software: Obfuscation, Watermarking, and Tamperproofing for Software Protection, reveals how to detect attacks on software: when a program is running on corrupted hardware and operating systems, when it is running under emulation and when the correct dynamic libraries have not been loaded, for example.

Authors Christian Collberg and Jasvir Nagra reveal how to check for software tampering by inspecting a program's code, computational results and execution environment.

See sidebar below to listen to an interview with the author.


Surreptitious Software
Chapter 7: Software Tamperproofing

Table of contents:
[IMAGE] Software tampering definitions
[IMAGE] How to check for software tampering

Download Chapter 7 of "Surreptitious Software" as a .pdf


An adversary's goal ...
To continue reading for free, register below or login To read more you must become a member of

is to force your program P to perform some action it wasn't intended to, such as playing a media file without the proper key or executing even though a license has expired. The most obvious way to reach this goal is to modify P's executable file prior to execution. But this is not the only way. The adversary could corrupt any of the stages needed to load and execute P, and this could potentially force P to execute in an unanticipated way. For example, he could force a modified operating system to be loaded; he could modify any file on the file system, including the dynamic linker; he could replace the real dynamic libraries with his own; he could run P under emulation; or he could attach a debugger and modify P's code or data on the fly.

Your goal, on the other hand, is to thwart such attacks. In other words, you want to make sure that P's executable file itself is healthy (hasn't been modified) and that the environment in which it runs (hardware, operating system, and so on) isn't hostile in any way. More specifically, you want to ensure that P is running on unadulterated hardware and operating systems; that it is not running under emulation; that the right dynamic libraries have been loaded; that P's code itself hasn't been modified; and that no external entity such as a debugger is modifying P's registers, stack, heap, environment variables, or input data.

In the following definition, we make use of two predicates, Id (P, E) and Ia (P, E), which respectively describe the integrity of the application (what the defender would like to maintain) and what constitutes a successful attack (what the attacker would like to accomplish):

Definition 7.1 (Tampering and Tamperproofing). Let Id (P, E) and Ia (P, E) be predicates over a program P and the environment E in which it executes. P is successfully tamperproofed if, throughout the execution of P, Id (P, E) holds. It is successfully attacked if, at some point during the execution of P, Ia (P, E) / not Id (P, E), holds and this is not detectable by P.

For example, in a cracking scenario, Ia could be, "P executes like a legally purchased version of Microsoft Word," and Id could be, "The attacker has entered a legal license code, and neither the OS nor the code of P have been modified." In a DRM scenario, Ia could be, "P is able to print out the private key," and Id could be, "The protected media cannot be played unless a valid user key has been entered / private keys remain private."

Conceptually, two functions, CHECK and RESPOND, are responsible for the tamperproofing. CHECK monitors the health of the system by testing a set of invariants and returning true if nothing suspicious is found. RESPOND queries CHECK to see if P is running as expected, and if it's not, issues a tamper response, such as terminating the program.

7.1.1 Checking for Tampering
CHECK can test any number of invariants, but these are the most common ones:

code checking: Check that P's code hashes to a known value:

if (hash(P's code) != 0xca7ca115)
return false;

result checking: Instead of checking that the code is correct, CHECK can test that the result of a computation is correct. For example, it is easy to check that a sorting routine hasn't been modified by testing that its output is correct:

for (i=0;i<(n-1);i++)
if (A[i]>A[i+1])
return false;

Checking the validity of a computed result is often computationally cheaper than performing the computation itself. For example, while sorting takes O(n log n) time, checking that the output of a sort routine is in sorted order can be done in almost linear time. Result checking was pioneered by Manuel Blum and has been used in commercial packages such as LEDA .

environment checking: The hardest thing for a program to check is the validity of its execution environment. Typical checks include, "Am I being run under emulation?", "Is there a debugger attached to my process?", and, "Is the operating system at the proper patch level?" While it might be possible to ask the operating system these questions, it's hard to know whether the answers can be trusted or if we're being lied to! The actual methods used for environment checking are highly system-specific.

As an example, let's consider how a Linux process would detect that it's attached to a debugger. As it turns out, a process on Linux can be traced only once. This means that a simple way to check if you're being traced is to try to trace yourself:

int main() {
if (ptrace(PTRACE-TRACEME))
printf("I'm being traced!n");

If the test fails, you can assume you've been attached to a debugger:

> gcc -g -o traced traced.c
> traced
> gdb traced
(gdb) run
I'm being traced!

Another popular way of detecting a debugging attack is to measure the time, absolute or wall clock, of a piece of code that should take much longer to execute in a debugger than when executed normally.

To see an example of the favorite debugging attack, download the rest of Chapter 7: Software Tamperproofing (.pdf).
To rate tips, you must be a member of
Register now to start rating these tips. Log in if you are already a member.

DISCLAIMER: Our Tips Exchange is a forum for you to share technical advice and expertise with your peers and to learn from other enterprise IT professionals. TechTarget provides the infrastructure to facilitate this sharing of information. However, we cannot guarantee the accuracy or validity of the material submitted. You agree that your use of the Ask The Expert services and your reliance on any questions, answers, information or other materials received through this Web site is at your own risk.

View the original article here

Labels: , , , ,


Post a Comment

Feel Free to Leave Your Comments/Thoughts Below

Links to this post:

Create a Link

<< Home