Back

The Number Quest

2021-05-01 . Written by fishie

Featured Image

be me

Intro

all this started when a friend contacted me about someone harassing her on telegram. she sent me a username and asked if i could get the phone number linked to the @ and i figured

yeah it shouldnt be too hard

i was wrong. it was hard. i just didn't know it yet


The Start

i started with writing a quick loop to generate the numbers for me

for (int i = 7000000; i < 7999999; i++)
      {
        Console.WriteLine("Number: +960 " + i);
        StringBuilder sb = new StringBuilder();
        sb.AppendFormat("\n{0},{1}", "Name", i);
        File.AppendAllText("Dhiraagu.csv", sb.ToString());
      }

as you can see its a simple loop which will generate a sheet of all possible Dhiraagu numbers. i did the same for Ooredoo numbers.

by the each sheet was 13MB - 15MB in size


after some research i found out about a file format called .vcf which seems to be the industry standard for storing contact data so i downloaded a csv to vcf converter and the file size came out to 83MB. yeah the whole large files thing is gonna be a pattern in this series so be prepared


anyways i zip up the file and it ended up being a nice 2MB. then i just sent it to a friend and had him import it to his phone. this is when things start going downhill. we all kinda just expected it to be a simple job. we did not expect the import to take hours and be so slow. a few hours into the import he told me that he cant do it anymore since it was overheating his phone.


so that was attempt 1


Attempt 2

i pull out android studio and open AVD. nothing too fancy just 8gb VM for me to work on. i gave it the same sheet and went to sleep leaving my pc running overnight.

9:50 AM - i checked my pc and the import process was at 35%. this was clearly a bigger process then i had originally anticipated so i leave the import process running and decided to check my options


Attempt 3

Google Contacts. turns out i can upload csv files to google contacts and have it sync to the phone. this seemed alot easier so i started uploading to google contacts.

20MB per file limit. Fuck

split -L 200000 contacts.csv

im sure if i split the files it would be fine

12k contacts per file limit. Fuck

ok ill just split it even more and upload

20MB of cloud storage limit. Fuck

ok so uploading to google contact failed due to all the restrictions they have so moving on


Attempt 4

"what if we directly edit the database"

a friend of mine found out all contact data is stored on a sqlite .db file called contacts2.db and suggested that i just directly inject the data into that. seemed like a simple enough idea so i open up adb and pull the .db file. +300MB file. bruhhhh. so turns out the way android stores contacts is optimized to be as fast as possible instead of as optimized for storage. this makes sense since the OS will need to pull up contacts picture and stuff the moment a call comes. anyways i didnt stop here. i decided to go and check the code for the contacts app since android is open source.


import com.android.vcard.VCardEntry;import com.android.vcard.VCardEntryCommitter;
import com.android.vcard.VCardEntryConstructor;import com.android.vcard.VCardEntryHandler;
import com.android.vcard.VCardInterpreter;import com.android.vcard.VCardParser;
import com.android.vcard.VCardParser_V21;import com.android.vcard.VCardParser_V30;
import com.android.vcard.exception.VCardException;
import com.android.vcard.exception.VCardNotSupportedException;
import com.android.vcard.exception.VCardVersionException;


i noticed these imports in the contact app so now i had to look at this code


SRC TO IMPORT Vcard Files

yeah that was a whole ass trip if i say so myself. alot of hashes and stuff so i decided not to enter directly into db. and then changed my mind and decided to make a c# script to inject numbers into the db. so i look up how to use sqlite with c# and then gave up for real this time


Attempt 5

"What if i Just write an App"


    for (int i = 7000000; i < 7999999; i++) {
      DisplayName = String.valueOf(i);
      MobileNumber = "960"+String.valueOf(i);
      ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
      ops.add(ContentProviderOperation.newInsert(
          ContactsContract.RawContacts.CONTENT_URI)
          .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
          .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
          .build());
      //------------------------------------------------------ Names
      if (DisplayName != null) {
        ops.add(ContentProviderOperation.newInsert(
            ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
            .withValue(ContactsContract.Data.MIMETYPE,
                ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
            .withValue(
                ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
                DisplayName).build());
      }
      //------------------------------------------------------ Mobile Number
      if (MobileNumber != null) {
        ops.add(ContentProviderOperation.
            newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
            .withValue(ContactsContract.Data.MIMETYPE,
                ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
            .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, MobileNumber)
            .withValue(ContactsContract.CommonDataKinds.Phone.TYPE,
                ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)
            .build());
      }
      // Asking the Contact provider to create a new contact
      try {
        getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
        etContactName.setText(DisplayName);
        etContactNumber.setText(MobileNumber);
      } catch (Exception e) {
        e.printStackTrace();
        Toast.makeText(this, "Exception: " + e.getMessage(), Toast.LENGTH_SHORT).show();
      }
    }

yeah uhh the app was a horrible idea. it works its just bad. idk why i expected an app to import any faster then a system app could. but in my defense the app was generating everything on the fly instead of importing from a large file. but yeah it failed


Attempt 2 part 2

so this whole time i had the vm running and i noticed it wasn't using that much ram. and then it hit me. i went and checked the settings. 1GB of ram. i give it like 5GB of ram and start over and it went alot faster then before. still not fast enough but yeah it was working. so i installed telegram and setup an alt account to sync the contacts since i didn't want my main account to have a huge contacts list and at first i thought it was working. and then after a while i got a bit suspicious and decided to check telegram privacy settings and then it hits me


users who add you number to their contacts will see it on telegram only if they are your contacts


yeah. this was not a gamer moment but i decided to still import the list just for the sake of doing it cause why not. not everyone can say they have the phone number of everyone in maldives. and then the worst thing happened at 40% import

out of storage

yup 8GB of storage can hold 400k contacts so as im writing this i gave the vm 32GB of storage and have it importing the numbers