Programming
What you should know before you start application development on the Android system
Mar 20th
First of all, if you want to start developing Android applications you’re going to first have to get used to the Java programing language because this is the means by which you’ll code your applications. Of course, if you pretty savvy with C++ or some other object oriented language then simply having some good Java tutorials bookmarked (i like this one) and learning it on the way will not be a problem if you think you’re up to challenges that lie ahead.
Now, what is an Android system? It’s practically a complete development environment with a complete software stack which contains the operating system (based on the Linux 2.6 kernel), a middle-layer application framework, a set of C/C++ libraries used by various components of the system to which you have access through the application framework mentioned above, and some core applications that you can also have access to, programmatically (I’ll explain below how why this is possible).
Having the Linux 2.6 Kernel at the core of the operating systems makes the platform pretty safe and well established when considering the Linux Kernel process management, memory management, networking stack, and driver model have undergone a long and arduous process of R&D for years.
The most important thing you need to know is that each application runs in its own safe-box: it has a unique user ID assigned by the OS, a unique process and therefore a unique virtual machine. No application can access the files or the memory of another one without being allowed to do so by Android’s kernel system.
Application Components:
The second most important thing is the way applications are structured. Each application can be comprised of four distinct parts called Application Components: the Activities, Services, Content Providers and Broadcast Receivers components. What is remarkable is that from your application you can access components that belong to a different application and this is not achieved by loading the code of that component into your process’ address space; no, it’s simply executed within its own kernel assigned process that has its uniquely assigned user ID. Because the Android system allows every application to start another application’s component you can practically use components from already developed applications into your own as if they are an integral part of your program. Pretty neat!
Because each application is loaded by its own process into its own address space, and because each application can start (use) any others’ component this means that there is no central station, no entry point of the whole system or as Android’s Documentation puts it “Android applications don’t have a single entry point (there’s no main() function, …..)“.
What are the application components? Activities are simply a singe screen or window that contains a user interface. A certain application can contain lots of activities designed to achieve a specific goal. They all are part of the application even though they are treated as separate when you program their functionality.
Services are simply background processes which can run for the whole execution time of the application. You can think of them as the core/heart of you application because they can coordinate the activities for the other components, they can trigger specific actions at certain times, they can access the network, etc.
Broadcast receivers are simply listeners for system broadcasts or application broadcasts. Your own application can generate broadcasts that can be catched by Broadcast receivers. These components can have a wide variety of uses one being that they can be used as triggers in your application’s workflow logic when certain system events or other application generated events take place.

Android Architecture
And finally, Content Providers. They are data storage providers: databases, file system data, web storage, etc., these can all be accessed by means of a Content Provider. What’s interesting is that different applications can share (read, modify) data contained in the same Content Provider object which is practically a shared set of application data; one interesting example is the contacts (ContactsContract.Data) Content Provider which contains user contact information (such as a phone number) and its associated metadata (such as whether it is a work or home number, email, etc) and can be accessed and modified by applications that have the appropriate privileges (meaning the ones that have been programmed to have these privileges, and subsequently have been installed by the user of the device).
More >
How to write a “Hello World” Safari Extension in Windows
Mar 13th
We’re going to build a simple Safari extension that will insert a bolded, italicized, Hello World text into the web-page of the current tab after it is loaded.
We’re going to use Safari 5.0 or later in order to have access to Extension Builder, that is, the means by which we’ll build our extension. Extensions were introduced in Safari 5.0, and were disabled by default, so in Safari 5.0 you must enable extensions in the Develop menu before you can show Extension Builder. Extensions are enabled by default in Safari 5.0.1 and later.
[Before we start coding]:
The Safari Extensions Development Guide states that before you can build and install an extension, you need to install a developer certificate. You obtain a certificate by first signing up for the Safari Developer Program at http://developer.apple.com/programs/safari/. You must first create an account and register all your personal information (phone, address, country code, etc – there’s no need of course to enter genuine information if you care for you privacy on the Internet – bogus data will suffice) .
You’ll obtain an Individual ID that will be usable for a period of 12 months. You then have to access http://developer.apple.com/membercenter/index.action and install your certificate by double-clicking the Developer Certificate Utility icon in order to Request and manage your Apple-issued Certificates for Mac and Safari. This launches the Certificate Import Wizard on a Windows machine. You then have to click Create Certificates, then Add Certificate and follow the instructions. Pretty arduous operation compared to what you have to do to get things working in Chrome or Firefox but hey, what are you going to do if you need the thing badly ?! (NOTE: Windows XP Professional and Windows Server 2003 will have to download the following Administration Tools Pack in order to be able to follow the above steps)
After all this you’ll be prompted to download your certificate (safari_identity.cer). You’ll have to double-click the downloaded *.cer file to install it.
[Activating Extension Builder]:
In order to use Extension Builder we’re going to first activate it; we do this by enabling the Safari developer tools when we click “Show Develop menu in menu bar” checkbox in the Advanced pane of Safari Preferences, as shown below. You can access Safari Preferences by clicking the top-right gear button that says “Display a menu of general Safari settings“.

How to activate Develop menu in Safari
We then go to the Develop menu and click Show Extension Builder; In the displayed dialog we hit the + button on the left-bottom and click New Extension, chose the path and the folder name and then insert the required fields of your extension:

Extension Info, Details, Versions, Website Access, Global Page, and Global Storage Settings
The required fields for the above are :
- 1. Display Name: the visible name of your extension
- 2. Bundle Identifier: this is a string in reverse DNS format : your type of website (com, gov, edu, org, and so on), your company name, and the extension name, separated by dots -> ex: com.lexdesign.hello.
- 3. Display Version: the displayed version number for your extension.
- 4. Bundle Version, that is, the internal version number used by the OS. One or more digits separated by periods (ex: 1 or 4.1.2). This is the version number Safari uses when checking for updates.

Chrome, Extension Scripts, and Settings
The optional fields above can contain the following :
- The Extension Chrome section can include am Extension Bar to be included below the bookmarks bar and above the tab bar, which is uniquely reserved for your extension, Context Menu Items, and Toolbar Items, that is, buttons added to the main Safari toolbar (not your specific extension bar).
- The Injected Extension Content section can include Start Scripts, that is, scripts executed before the webpage is loaded, End Scripts which execute when the body tag’s onload event occurs, and Style Sheets: CSS coding used to style the HTML.
Of course there are a lot of other fields. If you want to get the grips with all of them you can check Apple’s Safari Extensions Development Guide -> Using Extension Builder.
Now that we’ve bootstrapped the basic Safari Extension Starting Kit we will start to code the extension that will insert a bolded, italicized, Hello World text into the web-page of the current tab after it is loaded. This application can have various interesting uses: it could be used to insert specialized controls into specific websites that lack certain idiosyncratic features that the user may demand. Let’s begin!
[Injecting the text]:
inject.js is going to be added as an End Script in the Injected Extension Content section of Extension Builder. Being an end script means that the *.js file will be executed after the body tag’s onload event occurs. We’ll also use jQuery for easy manipulation of the DOM. We’ll insert jQuery as an End Script also.
You can get the latest, Minified (compressed) jQuery from http://docs.jquery.com/Downloading_jQuery.
Here is the inject.js file that will insert our Hello World text :
// <inject.js> insert a Hellow World text into the body of the document
function PageShowHandler(event)
{
injectText();
}
function injectText()
{
// get the document body
var pageBody = jQuery('body', document);
console.log('entered injectText');
pageBody.prepend('<h1>Hello World</h1>');
}
// wait 100 ms in order for jquery-1.5.1.min.js to be injected also
// if you don't want to wait just change the order of loading of jquery-1.5.1.min.js
// and inject.js in Extension Builder-> Injected Extension Content -> End Scripts
setTimeout(PageShowHandler, 100);
Please notice that we use the jQuery .prepend( content, [ content ] ) function that inserts content, specified by the parameter, to the beginning of each element in the set of matched elements.
Also, instead of directly executing the PageShowHandler function to insert our text into the body of the document, we user a timer and waited 100ms in order for jQuery to load. So, if you want to instantly use PageShowHandler, without a time, you should change the order of injection of the two javascript files in Extension Builder -> Injected Extension Content -> End Scripts as below:

The order of injection matters; specify the jQuery file first
More >
How to move the position of a certain bit within a byte ( coding the C language )
Feb 16th
You want to move bits inside a byte? Unfortunately, there aren’t any standard functions that deal with these sort of issues so we will have to use some smart and easy hacks.
First of all we need to use the tilde operator (~). Tilde is a bitwise not operator; this practically means that applying it to a certain operand’s binary value converts all the 1s to 0s and viceversa (~b0001 0010 = b1110 1101).
So what’s the use of tilde in our little program. We’re going to use it to create a mask that will delete (make 0) the bit of a certain location, that is, the bit we’re trying to move to another position, but we’ll also delete the bit from the destination position.
For example we have the byte 0xc3, and we need to move the bit from position 1 to position 5. Tilde will create a mask that will be used to delete the bit in position 1 (all the mask’s bits are 1s besides the bit at the position we’re trying to delete from which is of value 0) and position 5 (see line 14 and 15).
The mask achieves the delete of the bit by being AND-ed with our byte. Then we will OR the byte that we deleted the bits from (oldvalue) with another mask that contains the bit – of which value we read at line 12 with 0×01 & ((*our)>>indexold) – we will be writing at position 5. This new mask is of course made of all zeros besides the bit at position 5 which is of value valuetochange(=1 in our case) :
// example 1 (move bit from position 1 to position 5)
// 1100 0011
// ^ ^ BYTE MASK DEL BIT
// bit to be changed position has value 1
// 1100 0011 & 1111 1101 = 1100 0001
// 1100 0001 & 1101 1111 = 1100 0001
// DEL BIT MASK NEW BYTE
// 1100 0001 | 0010 0000 = 1110 0001
So practically we begin by registering the value of the bit we want to move in the valuetochange variable. We then delete the bits from both the current position of the bit we want to change the position of and its future position. Finally, we write the value from valuetochange into out byte. This is all achieved by:
// valuetochange = 0x01 & ((*our)>>indexold); // get the value of the bit to be moved oldvalue = (*our) & (~(1<<(indexold))); // del the bit from position indexold oldvalue = oldvalue & (~(1<<(indexnew))); // del the bit from position indexnew newvalue = oldvalue | (valuetochange<<(indexnew)); // write bit in new position (indexnew) //
Here’s all the code. I’ve compiled it using Visual Studio 2010, but earlier version should suffice for this little project.
#include <stdio.h>
#include <malloc.h>
typedef unsigned __int8 byte;
byte move(byte* our, int indexold, int indexnew)
{
byte oldvalue;
byte newvalue;
byte valuetochange;
valuetochange = 0x01 & ((*our)>>indexold); // get the value of the bit to be moved
printf("value to change : %d\n", valuetochange);
oldvalue = (*our) & (~(1<<(indexold))); // del the bit from position indexold
oldvalue = oldvalue & (~(1<<(indexnew))); // del the bit from position indexnew
printf("deleted: %x\n", oldvalue);
newvalue = oldvalue | (valuetochange<<(indexnew)); // write bit in new position (indexnew)
return newvalue;
}
int main()
{
byte* example_byte;
byte* new_byte;
example_byte = (byte*)malloc(sizeof(byte));
new_byte = (byte*)malloc(sizeof(byte));
*example_byte = 0xc3; // hex 0xc3 = binary 1100 0011
printf("\n");
//*****************************************************
// example 1 (move bit from position 1 to position 5)
// example_byte 1100 0011
// ^ ^
// memorize bit -> valuetochange = 0x01 & ((*our)>>indexold) = 1
// 1100 0011 & 1111 1101 = 1100 0001 delete bit from oldindex (1)
// 1100 0001 & 1101 1111 = 1100 0001 delete bit from newindex (5)
// new_byte 1100 0001 | 0010 0000 = 1110 0001
*new_byte = move(example_byte, 1, 5);
printf("old byte : %x\n", *example_byte); // 0xc3 (1100 0011)
printf("new byte : %x\n", *new_byte); // 0xe1 (1110 0001)
printf("\n");
//*****************************************************
// example 2 (move bit from position 6 to position 3)
// example_byte 1100 0011
// ^ ^
// memorize bit -> valuetochange = 0x01 & ((*our)>>indexold) = 1
// 1100 0011 & 1011 1111 = 1000 0011 delete bit from oldindex (6)
// 1000 0011 & 1111 0111 = 1000 0011 delete bit ftom newindex (3)
// new_byte 1000 0011 | 0000 1000 = 1000 1011
*new_byte = move(example_byte, 6, 3);
printf("old byte : %x\n", *example_byte); // 0xc3 (1100 0011)
printf("new byte : %x\n", *new_byte); // 0x8b (1000 1011)
printf("\n");
//*****************************************************
// example 3 (move bit from position 2 to position 6)
// example_byte 1100 0011
// ^ ^
// memorize bit -> valuetochange = 0x01 & ((*our)>>indexold) = 0
// 1100 0011 & 1111 1011 = 1100 0011 delete bit from oldindex (2)
// 1100 0011 & 1011 1111 = 1000 0011 delete bit from oldindex (6)
// new_byte 1000 0011 | 0000 0000 = 1000 0011
*new_byte = move(example_byte, 2, 6);
printf("old byte : %x\n", *example_byte); // 0xc3 (1100 0011)
printf("new byte : %x\n", *new_byte); // 0x83 (1000 0011)
printf("\n");
//*****************************************************
// example 4 (move bit from position 2 to position 4)
// example_byte 1100 0011
// ^ ^
// memorize bit -> valuetochange = 0x01 & ((*our)>>indexold) = 0
// 1100 0011 & 1111 1011 = 1100 0011 delete bit from oldindex (2)
// 1100 0011 & 1110 1111 = 1100 0011 delete bit from oldindex (4)
// new_byte 1100 0011 | 0000 0000 = 1100 0011
*new_byte = move(example_byte, 2, 4);
printf("old byte : %x\n", *example_byte); // 0xc3 (1100 0011)
printf("new byte : %x ", *new_byte); // 0xc3 (1100 0011)
printf("\n");
free(new_byte);
free(example_byte);
return 0;
}
More >
C# UDP Datagram Client and Server on the local computer
Jan 3rd
We will present a simple code for generating a UDP Datagram containing a simple word that will be sent from the local computer (UDP port 20000) and then read by a UDP server located on the same PC.
We’ll use C# as an example. The C#.NET language being based on a bytecode environment that achieves bounds checking on all arrays is the perfect networking programming language for beginners because they don’t also need to worry about stack buffer overflow vulnerabilities that may leave some unknown doors left open to exploiters. The only thing you need to worry about is networking.
THE SERVER: server.exe will take as arguments only the port number ( [PORT] ) which it will use for listening to UDP datagrams. The server also knows the port number of the client sending the datagram and of course its IP address which, of course, it is identical to its own IP address because all we’re trying to achieve here is to send and receive a UDP datagram from the same PC. So lets get through the process!
First we’ll use Dns.GetHostName() to obtain the host name of the local computer which will then be used to obtain the data structure that contains the local host’s internet address information. This data structure called IPHostEntry contains a list of IP addresses (IPHostEntry.AddressList) and Aliases (IPHostEntry.Aliases) that are associated with the host. After we obtain the IP address of the server by accessing the first element in the IP address list (IPHostEntry.AddressList[0]) we create a local IP/PORT pairing (IPEndPoint server_endpoint) that will inform the Socket through which we will listen at the client’s datagram about the server’s IP and listening PORT number, and a remote IP/PORT pairing (IPEndPoint remote_endpoint) which will capture the IP and PORT number of the client, whose datagrams we are listening to, after we’ll call the Socket.ReceiveFrom Method.
After we create the server_endpoint we need to associate it to the Socket object of the server in order to be able to read client’s UDP datagram. This association will be done using the Socket.Bind Method that works on both connectionless (ex:UDP) and connection-oriented protocols (ex: TCP, SCTP).
After this, the only thing that remains to be done is to simply read the UDP datagram by using the Socket.ReceiveFrom(Byte[] buffer, ref EndPoint ep) Method. ReceiveFrom reads (receives) the datagram and stores the source endpoint (client) in EndPoint ep.
SERVER.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
// SERVER.CS
// This is a simple UDP server that receives a UDP datagram containing a random word to a server on the local computer
// usage server.exe [PORT], where [PORT] is the sever UDP port number of the local PC
namespace UDPLocalServer
{
class ProgramServer
{
static void Main(string[] args)
{
if (args.Length != 1)
{
Console.WriteLine("USAGE: client.exe [PORT] [MESSAGE]");
Environment.Exit(1);
}
byte[] message = new byte[128];
String server_name = Dns.GetHostName(); // Get the name of the sever
IPHostEntry server_host = Dns.GetHostEntry(server_name); // Internet host address information
IPAddress server_ip = server_host.AddressList[0]; // IP address of the server
IPEndPoint server_endpoint = new IPEndPoint(server_ip, Convert.ToInt16(args[0])); // IP and PORT pairing of the server
// Creates an IPEndPoint to capture the identity of the client when we'll use the Socket.ReceiveFrom Method
IPEndPoint remote_endpoint = new IPEndPoint(IPAddress.Any, 0); // IP and PORT pairing of the client
Socket server_udp_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
// Bind the Socket to the local endpoint
server_udp_socket.Bind(server_endpoint);
// Receive message from the remote local client
EndPoint ep = (EndPoint)remote_endpoint;
server_udp_socket.ReceiveFrom(message, ref ep);
Console.WriteLine(System.Text.Encoding.Unicode.GetString(message));
Console.WriteLine(ep.ToString());
}
}
}
THE CLIENT: client.exe will take as arguments the server’s port number ( [PORT] ) that will be used as the destination port for sending UDP datagrams and the word ( [MESSAGE] ) that will be sent to the server . The client will use local port number 20000 as the source port for sending the datagram and of course its IP address which, of course, it is identical to the UDP server’s IP address. Lets get through the client.cs code and analyze it.
As in the case of the UDP server, by using Dns.GetHostName() and IPHostEntry.AddressList[0] we’ll obtain the hostname and then the IP address of the local computer. Using this IP address and the port number 20000 we will create the local IP/PORT pairing (IPEndPoint client_endpoint) that will instruct Socket client_udp_socket to use this specific IP and PORT when we will send the datagram. Also we’ll need to create a remote IP/PORT pairing (IPEndPoint remote_endpoint) for the local Socket to know where to send the UDP datagram.
We then bind client_endpoint to Socket client_udp_socket. After this, we will use the Socket.Connect Method which takes remote_endpoint as argument in order to connect to the UDP server. Now we can send the message to the connected Socket (client_udp_socket) with the Socket.Send Method. Bare in mind though, we don’t necesarily need to use the Socket.Connect method to connect to the server in order to send UDP datagrams. Because UDP is a connectionless protocol we can skip this phase and send the datagram using the method Socket.SendTo which doesn’t need a connected socket in order to send the datagram.
CLIENT.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
// CLIENT.CS
// This is a simple client that sends a UDP datagram containing a random word on the local computer's UDP server
// usage client.exe [PORT] [MESSAGE], where [PORT] is the sever UDP port number of the local PC and [MESSAGE] is a random word
namespace UDPLocalClient
{
class ProgramClient
{
static void Main(string[] args)
{
if (args.Length != 2)
{
Console.WriteLine("USAGE: client.exe [PORT] [MESSAGE]");
Environment.Exit(1);
}
Int16 port_number_client = 20000;
String client_name = Dns.GetHostName(); // Get the name of the client's PC
IPHostEntry client_host = Dns.GetHostEntry(client_name); // Internet host address information
IPAddress client_ip = client_host.AddressList[0]; // IP Address of client
IPEndPoint client_endpoint = new IPEndPoint(client_ip, port_number_client); // IP and PORT pairing the client
IPEndPoint remote_endpoint = new IPEndPoint(client_ip, Convert.ToInt16(args[0])); // IP and PORT pairing of the server
Socket client_udp_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
// Bind the Socket to the local endpoint
client_udp_socket.Bind(client_endpoint);
// Connect the UDP Socket to the server endpoint
client_udp_socket.Connect(remote_endpoint);
// Send the message
client_udp_socket.Send(System.Text.Encoding.Unicode.GetBytes(args[1]));
// Close the socket
client_udp_socket.Close();
Console.WriteLine(client_ip.ToString());
}
}
}
More >
Book Review – Inside Cyber Warfare written by Jeffrey Carr – Mapping the Cyber Underworld
Aug 26th
Internet connections have long ago ceased to represent only the blood vessels of our modern society. The complexity of what a few decades ago was a DARPA military research program has become akin to that of a global brain in which its neurons, the computers, are much more numerous than those found in the cerebral cortex of a cat.
Every aspect of our social, financial, and personal life is dependent on the hundreds of millions of Internet connections that cobble together all of our talents, ideas, visions and bake these into all the technological wonders and “freedom of expression” liberties which we now gladly, but blithely, enjoy these days. If these connections cease to exist so would your modern life. For that matter even mild and average disruptions of the wired system belonging to this boundless and dense Internet environment can be easily translated into millions of dollars of loses and even human casualties.
“Opportunity only knocks once” could have been easily quoted by anyone before the advent the Internet and modern networking. But now, having the possibility to connect with anyone from anywhere, anytime we choose to do so, opportunity has stopped to be a gift of life with which only the lucky ones will meet. With all this honey an undesirable effect will emerge; because an unseen law of nature makes every convenience come with its price, we will hardly enjoy the fruits ripen by the Internet’s human-ideas-cohesion knack without party-poppers, whose intentions hardly coincide with those of the group comprised of us more civilized individuals, that will try to exploit every vulnerability of this global informational network. Every aspect of your life, your ideas, your social connections, your family, your “secrets”, even your daily schedule become less personal once you plug all of these into the globally wired Internet. Cyberwarfare has begun!
Inside Cyber Warfare – Check Reviews on Amazon.com
Inside Cyber Warfare – Check Reviews on Amazon.co.uk
If you think Cyberwarfare is only about petty Internet crimes like credit card forgery and fraud, Website defacements done by immature individuals in desperate need to prove something, and malware coded with the intent of causing normal people like you and me to mentally brake down and throw our Windows based PCs through the window, then you are badly mistaken. The evidence brought about by this book and the fact that it’s target audience are Information Warfare policy makers will convince you that Cyberwarfare can be as serious as the armed warfare between countries and even terrorism.
The 2010 Stuxnet worm first discovered in June by a security firm based in Belarus (VirusBlokAda) specifically infected Iranian computers using Windows OS as their operating system platform in order to pave their way towards the SCADA (supervisory control and data acquisition) control systems used in Iran; the virus was supposedly coded by professionals to target Iranian nuclear power plants, industry sectors, and important infrastructure networks that used SIEMENS control systems as their automation technology; this is the first computer virus specially designed by a team of computer programming professionals, industry specialists, and specialized hackers; the time, the money, and the complexity of the malware gives us pretty good evidence on the possible implication of US intelligence agencies in aiding these kind of groups both financially, logistically, and even in creating themselves these special divisions of informational warriors.
Informational Warfare of all types, complexity, and level of damage inflicted on enemies has been going on for a long time. Non-state hackers driven by political and religious beliefs, state sponsored youth group organizations, cyber mafias thieving unwary online navigators of tens of millions of dollars, major corporations, companies and internet providers led by the urges of high profit, they all are part of this cyber war, and in one way or another, willingly or not, they pave the way and help build the “informational infrastructure” that will make computer viruses and specialized malware the future bullets that are going to be used by nations in order to wage war one upon another.
Jeffrey Carr’s Inside Cyber Warfare provides ample evidence for the information war stories that wandered in the mainstream media and alternative media at the end of the 20th century and the beginning of the 21st. The story about People’s Republic of China (PRC) hackers’ war waging upon U.S. government websites , the cyberwar between Israeli and Palestinian hackers due to the Israel’s Operation Cast Lead against Palestine, the Russian cyberwar between Chechnya, Georgia, and Estonia, where clear evidence for state sponsored hacking divisions is provided by the author, the 2009 Iranian presidential elections, and much more are analyzed in this very readable text which paints with unchallengeable arguments the not so rosy picture of Internet Dynamics.
Even Hacking techniques are given a non-shallow attempt at explaining in order to make their picture clearer. The book provides examples of attacks done by hackers using DDOS (Distributed Denial of Service) techniques, SQL Injection (SQLi), Buffer Overflow vulnerabilities, Backdoor malware, social engineering techniques applied using social networking websites like Twitter and Facebook, and the list can go on. Even though all these methods are also used by cyber criminals for extorsion, industrial sabotage, theft, revenge, economical espionage, they can also be ferocious, anonymous (sometimes untraceable) tools that can be easily used by terrorists, political activists and special state departments in order to wage war on enemy countries.
More to this, a lot of the text in this book engages in an interesting debate and argumentation onto the possible policy measures which state departments, intelligence agencies, and international organizations have adopted and will need to adopt in order to fight cyber crimes, cyber terrorism, and ultimately cyber warfare. Overall, the book deserves a score of 8 out of 10. Highly recommended for programmers, IT specialists, and government and intelligence agency policy makers, even though it can be easily enjoyed by anyone interested in the subject.











