Installing Games and Applications on an AT&T LG Shine (CU720) through the USB data cable

This guide assumes you know how to use BitPim and a hex editor.
Make sure to backup anything you change, I will not provide you with any files you lose.

If you have a decent bandwidth plan with AT&T then you don't need this guide. It is much easier and safer to download the jar and have the phone handle the installation process. If you need to know how check out the guide posted here, keep in mind that the first step about unlocking your phone is not necessary for AT&T (at least not for the phone they provided me). If you want an alternative to waphq and have your own web server you can use this.

Disclaimer

This guide has only been tested by me on my phone, I cannot guarantee it will work on yours.

There has been a report of this guide bricking a phone, that issue resolved itself but keep in mind that there is always a possibility of something going wrong when modifying core phone files.

I have used this guide to replace most of the default applications/games on my phone. The following apps I did not remove as they did not bug me as much as the demo games/apps littering my "Games" and "Applications" folders.

They also have a different "type" option so I do _not_ know if this guide will work at replacing them.

Changes

Limitations

Connecting to your phone with BitPim

Make sure your phone has the LG drivers installed and set your phone's connect mode to "Data Service" (Settings > Connection > USB Connection Mode). Start BitPim, it should detect your phone as 'Other CDMA phone.' Now open the BitPim settings and set the phone type to LG-VX8700. You will have to do this every time you connect your phone to BitPim and every time you reset your phone.

Once your phone is manually set go to the file manager page and expand the root item. This will take a few minutes to complete. After it is complete you will see your phone's filesystem. If this is your first time connecting your phone your should backup the filesystem (or at least the LGAPP section) in case you need to restore it later.

Updating an existing application or game

If you do not care about changing the name/location:

  1. Find the application you want to replace inside LGAPP\Media\Java\ams
  2. Backup the application directory
  3. Create a temporary directory on your computer to work from
  4. Copy the new application jar to the temporary directory
  5. Create a .jad file for your .jar. (I use JADMaker)
  6. Rename your .jar and .jad to 'jar' and 'jad'
  7. Transfer the new jar and jad to the phone
  8. That should be it, the new application should run when you start the old one. (It may fail the first time)

If you want to change the name/location:

  1. Find the application you want to replace inside LGAPP\Media\Java\ams
  2. Backup the application directory
  3. Create a temporary directory on your computer to work from
  4. Copy the new application jar to the temporary directory
  5. Create a jad file for your jar. (I use JADMaker)
    The jad file is a plain text document containing information about the jar.
    The MIDlet-Name option inside the jad file is the name that displays on the exit popup (when you push end on your phone), you might want to make sure this matches whatever name you set in step 7
  6. Download LGAPP\Media\Java\_ms_db_ and backup a copy of it
    I could not find an editor for this file type, so to change it you need to get a copy of 010 Editor. After you install 010 Editor open the _ms_db_ file with it and load this template.
  7. Expand the entry for the app you are changing in 010 Editor's Template Results pane.
    From here you can change the totalSize, name, and directory options.
    • To change the totalSize or directory just edit the template results
    • To change the name edit it in the hex editor, if the new name is shorter make sure to zero out the end of the string
  8. Remove the files from the existing app directory on the phone
  9. Transfer the new jar and jad to the phone
  10. Overwrite the _ms_db_ file with your new one then reboot your phone

Adding a new application or game

  1. Find the next available directory number inside LGAPP\Media\Java\ams
  2. Create a temporary directory on your computer to work from
  3. Copy the new application jar to the temporary directory
  4. Create a jad file for your jar. (I use JADMaker)
    The jad file is a plain text document containing information about the jar.
    The MIDlet-Name option inside the jad file is the name that displays on the exit popup (when you push end on your phone), you might want to make sure this matches whatever name you set in step 7
  5. Download LGAPP\Media\Java\_ms_db_ and backup a copy of it
    I could not find an editor for this file type, so to change it you need to get a copy of 010 Editor. After you install 010 Editor open the _ms_db_ file with it and load this template.
  6. Find another entry of the same type and select it by clicking on it's root in 010 Editor's Template Results pane. Copy the selected data then click on the next available entry position and paste it in. (Make sure to run the template again after you paste in new data)
  7. Expand the entry you just pasted in data for.
    From here you can change the totalSize, name, and currentId options. currentId should be the directory number plus one. After you update currentId the entry root will display the expected position for the currentId which you also need to change.
    • To change the totalSize, currentId, position, or directory just edit the template results
    • To change the name edit it in the hex editor, if the new name is shorter make sure to zero out the end of the string
  8. Update both of the numberOfEntries in the fileHeader structure to the new number of entries. (This is not always directly related to the highest currentId, sometimes the phone will skip a position when installing a game. To find the actual number manually count the number of non-empty entries.)
  9. Create the new app directory on your phone (LGAPP\Media\Java\ams\M###)
  10. Transfer the new jar and jad to the phone
  11. Overwrite the _ms_db_ file with your new one then reboot your phone

Troubleshooting

Known _ms_db_ options

There is still quite a bit about the data structure I don't know, if you have any other information on it contact me.

010 Editor _ms_db_ Template

//--------------------------------------
//--- 010 Editor v3.0 Binary Template
//
// File: _ms_db_
// Author: cowsonfire
// Revision: 0.1.1
// Purpose:  LG Shine CU720 Java/ams/_ms_db_
//
// Everytime you change _ms_db_ you need to restart the phone
//--------------------------------------
LittleEndian();

struct MSDB_FILE {
	struct MSDB_HEADER {
		short unknown1[6];
		int numberOfEntries1;
		int numberOfEntries2;
	} fileHeader <read=ReadHeader>;

	struct MSDB_ENTRY {
		int unknown0; // always 0
		short storageType <read=ReadStorageType>;
		short directory <read=ReadDirectory>;
		short position; // always (parent.currentId - 1) * 256
		short unknown1; // while this seems to always be 320 it is NOT the resolution
		int unknown2;  // always 1
		int totalSize; // the size of the files inside the M### folder
		char name[512];
		int unknown3[2];

		int type <read=ReadType>;
		int currentId <read=ReadCurrentId>;
		
		struct UNKNOWN3 {
			short unknown1[10];
			short unknown2[10];
			short unknown3[10];
			short unknown4[10];
			short unknown5[10];
			short unknown6[10];
			short unknown7[10];
		} unknown3;
	} info[150] <optimize=false, read=ReadEntry>;
} file;



string ReadDirectory(short &d) {
	string s;
	if (d == 2) {
		SPrintf(s, "Games (%d)", d);
	}
	else if (d == 3) {
		SPrintf(s, "Applications (%d)", d);
	}
	else if (d == 0) {
		SPrintf(s, "None (%d)", d);
	}
	else {
		SPrintf(s, "Unknown (%d)", d);
	}
	return s;
}

string ReadStorageType(short &t) {
	string s;
	if (t == 10001) {
		SPrintf(s, "Phone (%d)", t);
	}
	else if (t == 20002) {
		SPrintf(s, "External Memory Card (%d)", t);
	}
	else {
		SPrintf(s, "Unknown (%d)", t);
	}
	return s;
}

string ReadEntry(MSDB_ENTRY &a)
{
	if (Strlen(a.name) > 0) {
		int expected = (a.currentId - 1) * 256;
		if (a.position != expected) {
			string s;
			SPrintf(s, "%s; Unexpected 'position' value (Expected: %d, Found: %d)", SubStr(a.name, 5), expected, a.position);
			return s;
		}
		return SubStr(a.name, 5);
	}
	return "(None)";
}

string ReadHeader(MSDB_HEADER &a)
{
	string s;
	SPrintf(s, "Number of Entries: (%d / %d)", a.numberOfEntries1, a.numberOfEntries2);
	return s;
}

string ReadType(int &a)
{
	string s;
	if (a == 5) {
		SPrintf(s, "Application & Games (%d)", a);
	}
	else if (a == 7) {
		SPrintf(s, "Other (Music, Email) (%d)", a);
	}
	else {
		SPrintf(s, "Unknown Type (%d)", a);
	}
	return s;
}

string ReadCurrentId(int &a)
{
	string s;
	SPrintf(s, "%d (M%03d)", a, a - 1);
	return s;
}

Known Files

Credits

Links

Contact

If you have more information on anything missing in the guide or suggestions on making the guide better please let me know.