JME‎ > ‎

Self Replication

To Do

The BluetoothSearchSend example and the ProfileTester application need to be uploaded.


Of course it is not really possible to make an actual virus (in the classical sense of the word) for j2me without a device which allows installation and execution of an application without user permission.

So then what is this page about? 

Here you can find the exact instructions on how to create a self replicating midlet. This means the application contains code to send itself to another device.

In this particular example the midlet is replicated onto another device over bluetooth but this could be replaced by any other transfer mechanism. (such as infrared, internet, usb, whatever)

If the user gives the application permission for using bluetooth, the receiving device receives the file, then installs the received file and then starts the installed application, the process could be repeated infinitely.

Why is it tricky to replicate a midlet?

A running application can only access data inside its jar file, not the jarfile as a whole.

(unless the phone supports the file access api in which case it would still be hard to locate the jar file on the file system)

Which problems can not be solved?

  • some phones can only install jar files when there are downloaded in the browser.
  • obviously the sending phone needs to support the bluetooth api. jsr82


The easiest way to have the application forward itself is by packaging it inside itself several times. 

Obviously this is very inefficient and finite. 

The way I solved that is by re-inserting the zip file into itself just before sending it. 

Of course the application still needs to be packaged into itself once to be able to access it. J2ME does not allow reading the class files.

Optionally, additional files can be inserted to pass user data into the new generation. Applications with large resource files could insert these files to avoid having to include them into the inner zip file.

As the zip file is already compressed, it is stored into itself uncompressed.

This code does the trick:

A zip file consists of a series of local header and file blocks, followed by a central header for each file, concluded by a closing record. See the full zip specification for details.

A jar file is equal to a zip file, except for the extra field of the first local header which should contain 0xcafe0000.

If a new file is inserted after the existing files (just before the central header) the offsets of other files do not need to be modified.

A new central header must be added which points to the new local header. Which happens to be at the same position as the first central header in the original zip file.

These things must be altered in the closing record:

  • The position of the first central header is increased by 30 + filename length + file size.
  • The size of the central headers is increased by 46 + filename length
  • The number of files is increased by one.


I am not an expert on bluetooth, but here is how I did it:


Create a class which implements the DiscoveryListener interface.

Call startInquiry() on the discovery agent to start the inquiry.

GIAC mode works best for me.

The platform calls deviceDiscovered() for each discovered device and calls inquiryCompleted() when done or interrupted.


After selecting the device, a service offered by that device must be selected. The DiscoveryListener class is used for that too.

Call searchServices() on the discovery agent to start the inquiry.

UUID 0x1105 works best for me.

The platform calls servicesDiscovered() for each discovered service and calls serviceSearchCompleted() when done or interrupted.


To send a file to the inbox of a phone (as opposed to communication between j2me applications) the obex package is needed which is not supported by all phones.

This can be solved by using the Avetana ObEx library 

For some reason the connection url returned by the service record specifies the btgoep protocol which has to be replaced by the btspp protocol.

Create a ClientSession and HeaderSet then set the file name, file size and content type (application/java-archive), then create an Operation and write the file data into its OutputStream and keep your fingers crossed.


Different devices support different bluetooth profiles.I have tried FTP profile (which seemed obvious for this purpose) but that didn't work. It seems most devices support Push Profile (0x1105) but it is not always returned by the service search.

Use the ProfileTester sample application to find out which profiles are supported by your device.


To demonstrate the technology I made these sample applications: 

Chain Letter

The only actual functionality of this application (besides the self replication) is displaying and editing of a single string of text. The modified string is passed into the replicated "child" and allows the string to be extended by each new generation.


Pyramid Scheme 

New participants register by allowing the application to send a sms text message. (which costs 55 cents + operator fees) The income is paid to the referring participants (10 for the referrer, 9 to his referrer, 8 to the referrer above him and so on)

When a participant signs up 3 new people which each sign up 3 new people (and so on 10 levels deep) the profit at the top is 1300,00


Profile Tester

This is not a replicating application but is only used to do some diagnostics on the bluetooth capabilities of the receiving device.


What else?

J2ME is often used to make digital flyers. A bluetooth radio constantly tries to send the application to all devices it can reach attempting to spread it as much as possible.

If the application contains some discount code (or anything valuable to the user) users will spread the application to their peers thus hugely increasing the advertisers reach.

If you are an advertiser interested in such an application please contact arnodenhond (at) gmail.
Arno den Hond,
Mar 12, 2009, 2:19 PM
Arno den Hond,
Mar 12, 2009, 2:19 PM