+ Reply to Thread
Results 1 to 10 of 38

  1. PeroPero
  2. PeroPero Seduction Integration

Hybrid View

  1. #1

    Join Date
    Jul 2015
    Location
    Argentina
    Posts
    157
    Credits
    179

    Lightbulb

    Well, as far as my limited ActionScript knowledge can let me trace the code from decompiling the SWF file:

    Everything you do in the app (and I really mean everything; from clicking the splash screen button to buying items in the shop) is mapped into a tuple (name, flags, data object) and sent to the server for processing.

    Be aware that the following are just my guesses, and they can be completely wrong. Without access to the server code, or debugging/tracing the code during a playthrough, I cannot be sure of anything.

    Chance Times have four possible events (not counting the roulette spin ones, where you have one for each possible response, including each color stepup):
    • Step Up Finished: This one should trigger after all the step up spins are done. It should send the step up value to the server for chance event building (as far as I can guess, normal Chance Times are just treated as Step Up Lvl 0); and return the data needed to build the selection panel.
    • Chance Selected: This one should trigger after you have selected the card to open. It should send your selection to the server, and return the data needed to show results.
    • Open Card: This one should be the event that adds the reward card to your collection (or leves up the card if not new). It shouldn't send any new data, and return the data needed for adding/fusing the card.
    • Open Card Finished: This one should trigger after you've finished the card event (adding/fusing the card to your collection).


    There's also a lot of Gacha events and constants, but they all seem to be about the Gacha Window in the main app (where you choose the gacha to use, view the card lists, etc).

    I'm currently trying to see if any data is passed to the Chance Selected event regarding chosen card. The algorithm itself will remain unreachable for us, but depending on the data passed there, we'll know a bit of how this works:
    1. If no data about the chosen card is passed, then we can easily assume the algorithm ignores our choice completely.
    2. If data about the chosen card is passed, then we'll know the choice is relevant. Now, wether the cards are pre-calculated or not won't be reflected here, but it might be heavily implied so if this data is returned to the server.


    Okay, delving a bit more,

    I've found enough panels and event notifications to confirm that there are three parts to a chance time:
    1. Chance Time Panel
    2. Get Card Panel
    3. Integrate Card Panel

    as well as a boatload of micro-events in between them:
    1. Init event for each panel
    2. View event for each panel
    3. Action events for each step:
      • Select
      • Select Result
      • Select View
      • Use Item
      • Confirm Item
      • Use Item Result
      • Open Cards


    Once again, if the selection has an impact on the algorithm is unknown to us. Each step could be there for the simple purpose of keeping track of each interaction with the player, as well as for the need of selection values.



    And, finally, because my curiosity wouldn't allow me to leave this alone, packet phishing has led me to:

    After trawling through a lot of data with WireShark, and after understanding how the app works in sync with the server, I've located the following web service path as the call from the SELECT CARD event:

    Code:
    GET /Raidboss_Event-Chancetime/choice?playerId=853603&sessionId=26BLongBase64SessionId&format=json&select=5&token=20BLongHexadecimalTokenId
    Ignoring the session and token IDs (which I have erased for security reasons), and my User ID, we can see that the selection code is actually passed (5 here meaning bottom middle card).

    After decoding the 2.8KB block of data returned by that call, you get:
    Code:
    {
        "contents":{
            "player":{
                "playerId":"853603",
                "level":"35",
                "exp":{
                    "value":"36094",
                    "max":"37165"},
                "gold":"15402",
                "friend":{
                    "value":39,
                    "max":"39"},
                "actionPoint":{
                    "value":"88",
                    "max":229,
                    "recoverFinishTime":1436559511,
                    "recoverTime":8442,
                    "recoverInterval":60},
                "battlePoint":{
                    "value":0,
                    "max":6,
                    "recoverFinishTime":1436552659,
                    "recoverTime":1590,
                    "recoverInterval":300},
                "thumbnail":{AvatarImageURLsObject}
                "boost":false},
            "answer":[
                {"cardId":"121",
                 "src":{CardImageURLsObject},
                 "name":"Yukiko Hosaka",
                 "rarity":"N",
                 "level":84,
                 "at":"220"},
                {"cardId":"108",
                 "src":{CardImageURLsObject},
                 "name":"Maiko Mikami",
                 "rarity":"R",
                 "level":25,
                 "at":"660"},
                {"cardId":"49",
                 "src":{CardImageURLsObject},
                 "name":"Yukie Takenouchi",
                 "rarity":"N",
                 "level":69,
                 "at":"340"},
                {"cardId":"14",
                 "src":{CardImageURLsObject},
                 "name":"Mayumi Hashiguchi",
                 "rarity":"N",
                 "level":100,
                 "at":"200"},
                {"cardId":"46",
                 "src":{CardImageURLsObject},
                 "name":"Iori Kodama",
                 "rarity":"N",
                 "level":100,
                 "at":"260"},
                {"cardId":"44",
                 "src":{CardImageURLsObject},
                 "name":"Rio Iguchi",
                 "rarity":"N",
                 "level":100,
                 "at":"230"}],
            "card":{
                "before":{
                    "cardId":"46".
                    "src":{CardImageURLsObject},
                    "name":"Iori Kodama",
                    "rarity":"N",
                    "level":100,
                    "at":"2590"},
                "after":{
                    "cardId":"",
                    "src":{PeroImageURLsObject},
                    "name":"300 pero",
                    "rarity":"",
                    "at":""}},
            "isItem":1},
        "header":{
            "status":"OK",
            "error_msg":null}}
    The JSON code returned is quite self explanatory. There's all the data from my account (contents.player), all the data from the response (contents.answer), and the header data (header).

    You can also see how the answer contains all six cards to show (contents.answer.[0]), as well as the before/after data for adding/integrating the selected card (contents.answer.card), and the fact the returned card is actually an item/pero (contents.answer.isItem).

    I forgot to take a screenshot, but I can say the array of returned cards is in the exact order of revealed cards (Top-Left being 1st, Bottom-Right being 6th)

    This means that the selected value does impact the result returned by the server.
    However, once again, there's no data to point to any possible choice algorithm. What's more, the way the data is returned completely negates any chance the selection value being sent to the server may mean it does impact the choice itself, as it might just be sent so that the server knows how to build that response JSON object

    Last edited by YoshiEnVerde; 07-10-2015 at 12:46 PM.
    PPS ID: 853603 (YoshiEnVerde)
    Osawari Invite: 40VRKO15D3C537UUC2F4F

  2. #2
    Wait, does that mean you can see what the cards are beforehand, or did it not tell you the card data until you selected one?

  3. #3

    Join Date
    Jul 2015
    Location
    Argentina
    Posts
    157
    Credits
    179
    I will toss my coin to the choice-affects-algorithm size, mainly because from a programming view, if cards were pre-calculated (and not impacted by choice) it would be easier for the server to send all the result data when the chance event triggers, and just emulate the whole choice process locally.
    Instead, the server is contacted after the choice has been made, and returns all the data to show the result and apply the integration.

    My guess is that if goes something like this:
    1. Player triggers a chance time event
    2. Player is shown the choice panel
    3. Player chooses a card position, triggering a chance time card choose event
    4. App sends request for processing a chance time with a chosen card position
    5. Server runs an algorithm that creates 6 cards in an ordered fashion, based on all the chance time event's parameters (What stage is this? Is it a Gacha Ticket? 4th Event Ticket without an SR appearing? There were 4 stand up spins? etc)
    6. Server checks the card corresponding to the selected position
    7. Server processes the integration of checked card
    8. Server returns the result JSON packet with current player data, answer data, integration data, and header
    9. App recieves results and triggers the chance time choice reveal event
    10. Player and App interact for the set of chance time card integration events and panel
    11. Player is show whatever panel they came from before chance time event was triggered (with updated player data from response)


    - - - Updated - - -

    Quote Originally Posted by Kotono View Post
    Wait, does that mean you can see what the cards are beforehand, or did it not tell you the card data until you selected one?
    All the data from all 6 cards is returned as part of the answer to your choice. So no, you have no data before you choose your card.

    - - - Updated - - -

    The interesting part is that you could alter incoming and outgoing packages to force the game into giving you chance times (or whatever you want to get); but it would probably raise a hacking flag in the server at worst, or leave traces that can be found by admins at best (depending on the level of validation strictness the server does on each player's state).

    I'm actually glad with that, as I despise people laming a game with hacks, even as a COD minmaxer with the skills to build hacking apps (specially so)
    PPS ID: 853603 (YoshiEnVerde)
    Osawari Invite: 40VRKO15D3C537UUC2F4F

  4. #4
    I hope PeroPero server is the only one to know then hidden Cards untill a player pick a Card. If our computer have info about what the hidden Cards are before we pick a Card cheaters can make a simple program that enables them to have a free Card reveal all the time. The PeroPero server would not be able to see that the cheater have read some info in there own computers memery as long as the cheaters dont change the info.

    I dont like cheaters and hope the PeroPero is code is better than some other free Card games. I am no hacker and I newer made any tools like that. I am just interested to understand the game better so I can max my SR chance with in the Laws of the game. So I do statistic to see if Cards are better in some spots that others spots.

    I know from real slot mashimes that the owners some time chance the reward chance. If a mashine is unpopular they raise win chances. They dont tell players ablot this, When players discower it is a real good mashine owener lower win chances again. I newer really gamble for Money but I find interesting to try to find optimal tacktics.
    Last edited by Opalia24; 07-10-2015 at 02:46 PM.

  5. #5

    Join Date
    Jun 2015
    Posts
    1,916
    Credits
    1,639
    This was some nice data you gathered, really interesting. I must say your guess at how it works seems appropriate, with the server generating the cards after the answer has been sent.

    Thanks for the insight

  6. #6

    Join Date
    Jul 2015
    Location
    Argentina
    Posts
    157
    Credits
    179
    Quote Originally Posted by Opalia24 View Post
    I hope PeroPero server is the only one to know then hidden Cards untill a player pick a Card. If our computer have info about what the hidden Cards are before we pick a Card cheaters can make a simple program that enables them to have a free Card reveal all the time. The PeroPero server would not be able to see that the cheater have read some info in there own computers memery as long as the cheaters dont change the info.

    I dont like cheaters and hope the PeroPero is code is better than some other free Card games. I am no hacker and I newer made any tools like that. I am just interested to understand the game better so I can max my SR chance with in the Laws of the game. So I do statistic to see if Cards are better in some spots that others spots.
    I do have the skills and know-how to build such tools, but my sentiments mirror yours exactly. I could crack the flash code easily and trace everything to see how the algorithm worked, but I'd hate it if somebody (myself included) ever used such knowledge to cheat the game.

    As far as I can tell, the server does keep track enough to not be hacked this way (or, at worst, for admins to be able to trace any such cheating):

    1. Every time you hit the big pink GO button, your local app asks the server for your next spin result. That allows the server to actually make sure you're not changing packets to get the spin you want.
    2. Every time you enter chance time, your local app is only capable of letting you choose from 1 to 6, and then ask the server to draw the 6 random cards and tell you which one you got, and how that affects your current collection. That allows the server to avoid players from laming the chance time process.
    3. Every time you do anything that comunicates with the server, your app recieves an update to your stats (exp and pero included) from the state saved in the server. That means at the very least the server keeps those values recorded, and updates them on any triggered event.


    The only things you might be able to lame are:
    1. Modifying data packets to lie to your local app about spin results, which might, might, allow you to cheat the server.
    2. Duplicating a used my card reveal packet before executing the select chance time card event, in order to always get the cards data before selection.
    3. Modifying data packets, just like on item 1, but for focus related events, like attacking guards and such.


    However, just by looking at the average packets moved, you can tell that all these cheats would leave a very big neon-flashing marquee on any attempt, easy for admins to find.
    And that's only if the server doesn't bother to validate every passing packet, which would automatically raise a red flag for any admin to check.
    PPS ID: 853603 (YoshiEnVerde)
    Osawari Invite: 40VRKO15D3C537UUC2F4F

  7. #7
    May I ask how you learned how to do this? I don't want to intrude on your secrets but I've always been curious as to how some people go about manipulating their way into what should be safe information.

  8. #8

    Join Date
    Jul 2015
    Location
    Argentina
    Posts
    157
    Credits
    179

    Post

    No problem at all... not really any secret here.

    The main point is that I'm a proffesional in the IT sector (mainly business intelligence and software development) with over a decade of experience.
    That there gives me the ability to grab any program, and find some way of tracing the way it works (sometimes better, depends a lot on the language and design, really).

    With that out of the way, I first saved the PeroPero Saimin page to the disk to get my hands on the game's swf file.
    Then, I googled until I found a good enough Flash SWF decompiler, which basically tries to give you readable action script source code from a swf file.
    After that, I just read the resulting code, trying to get a general idea of how the program worked.
    Once I had a bare understanding of that, I looked for the part where gacha/chance was handled.

    That's how I got the first part of my post (BTW, later I realized I had made a few mistakes in my assumptions, but by that time they were irrelevant).

    Once I knew that the app was constantly asking the server for every scrap of data and every event processing, I opened one of my trusty packet sniffers.
    I pinged Nutaku to get a general idea of what IP it was using, and then started watching over any TCP/IP packet that was moved between my machine and Nutaku.
    Then, I basically played the game while watching the packets go by, until I had a good idea of how PeroPero's communication protocol worked (I can tell you, for example, that Nutaku handles the load balancing, making sure we all have access to the game no matter the consumption of bandwidth, by proxying everything through an Amazon AWS Service).

    After that, it was just a matter of analyzing the HTTP packets to see what was being transmitted.
    I waited until I got a Chance Time in the event spin, and started reading all the packets very closely.
    The fact that the data is not encrypted at all helped inmensely (now that would have been a nightmare to bypass).


    Once again, just enough experience to know what to look for, and what tools to use, and patience. Lots of patience.

    BTW, if anybody wants to know, the tools used were FFDec for decompiling the swf file, and WireShark for packet sniffing. Besides that, just Sublime Text as text editor to power through pieces of code/data.
    PPS ID: 853603 (YoshiEnVerde)
    Osawari Invite: 40VRKO15D3C537UUC2F4F

  9. #9

    Join Date
    Jul 2015
    Location
    Chile
    Posts
    266
    Credits
    292
    Well, thanks [MENTION=92]YoshiEnVerde[/MENTION], your analysis pretty much solves the mistery xD.
    Though I'd really like to be able to analyse the code further, but the conclusions makes sense to me, so I agree.

    Didn't even wanted to use WireShark, but I guess there's no problem in just sniffing some packages and observe traffic.
    LoV ID: Danex (RIP LoV)
    PPS ID: 574023 (Dropped)
    Currently Playing: MWA

    My signature :3 Newbie stuff, don't kill me :c


Posting Permissions

  • You may post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts
  •