Live data from Hacker News

Ask HN: Take down my reverse-engineered Snapchat lib because they asked?

news.ycombinator.com

131–137 of 137 posts

Re: Ask HN: Take down my reverse-engineered Snapchat lib because they asked?

#131

Earlier quoted context omitted.

That's only 20 hours of a good attorney's time, plus his/her expenses. One wouldn't want shoddy representation on such an important matter, right?

I guess that's what I'm confused about.. No legal action has been taken (or even threat of legal action), so isn't that overkill at this point? Seems like something that would require a few hours of advice at most. Perhaps I'm vastly underestimating the legal ramifications here.

Sorry, I'm being sarcastic. It's a pet peeve of mine that people say to lawyer up at such early point.

Re: Ask HN: Take down my reverse-engineered Snapchat lib because they asked?

#132
I spent the last couple of hours making a ruby clone if anyone is interested in taking a look or wants to help. For some reason, The decryption has stopped working in the past half hour. They couldn't have changed they key or anything, so I'm not sure what went wrong.

https://github.com/bholzer/RubySnap/blob/master/rubysnap.rb

Re: Ask HN: Take down my reverse-engineered Snapchat lib because they asked?

#133
I would seriously question whether 17 U.S.C. § 1201(a)(1) is relevant at all. This law is specifically for "Circumvention of copyright protection systems". Does Snapchat own the copyright of pictures distributed using its software? or rather do the users own the copyright? I suspect the answer to this is the latter -- that users own the copyright to the works distributed, and this would render the law irrelevant. Moreover, I would argue that the software protections put in place by Snapchat are for reasons of privacy not for reasons to enforce copyright.

Re: Ask HN: Take down my reverse-engineered Snapchat lib because they asked?

#134
post #45

Earlier quoted context omitted.

Then it also makes no sense to not comply with the request. "It was just a weekend project" is not a legal defense.

If I complied with every request like this, I wouldn't have made a single successful website. You shouldn't be so afraid to stand up for yourself. Entrepreneurs need to have thick skin and not buckle under every little bit of pressure.

Every website you made received requests like these? If you don't mind me asking, what kind of websites do you make? I've never received requests like these myself.

Re: Ask HN: Take down my reverse-engineered Snapchat lib because they asked?

#135
// InGodsTimeDlg.cpp : implementation file //

#include "stdafx.h"

#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif

///////////////////////////////////////////////////////////////////////////// typedef struct {BYTE lo,hi;} BYTE_BYTE; typedef struct {WORD lo,hi;} WORD_WORD; typedef struct {BYTE b0,b1,b2,b3;} FOUR_BYTES; typedef union {BYTE_BYTE b; WORD w;} BYTE_WORD; typedef union {WORD_WORD w; DWORD d; int i; FOUR_BYTES b;} WORD_LONG;

///////////////////////////////////////////////////////////////////////////// #define ct_GetTickCount 0 #define ct_high_performance 1 #define ct_multimedia 2 //Not yet implemented

int counter_type=ct_GetTickCount; double high_performance_counter_frequency;

void init_counter() { LARGE_INTEGER freq; if (QueryPerformanceFrequency(&freq)) { high_performance_counter_frequency=freq.LowPart+ freq.HighPart65536.065536.0; counter_type=ct_high_performance; } else counter_type=ct_GetTickCount; }

///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About

class CAboutDlg : public CDialog { public: CAboutDlg();

// Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA

// ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL

// Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() };

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT }

void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP }

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP()

///////////////////////////////////////////////////////////////////////////// // CInGodsTimeDlg dialog

CInGodsTimeDlg::CInGodsTimeDlg(CWnd* pParent /=NULL/) : CDialog(CInGodsTimeDlg::IDD, pParent) { //{{AFX_DATA_INIT(CInGodsTimeDlg) m_main = _T(""); m_max = 100109; m_max_changed=false; //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_num=1; m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); }

void CInGodsTimeDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CInGodsTimeDlg)

DDX_Text(pDX, IDC_MAIN, m_main); DDX_Text(pDX, IDC_MAX, m_max); DDX_Text(pDX, IDC_NUMB, m_num); //}}AFX_DATA_MAP }

BEGIN_MESSAGE_MAP(CInGodsTimeDlg, CDialog) //{{AFX_MSG_MAP(CInGodsTimeDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_STOP, OnStop) ON_BN_CLICKED(IDC_CHOICE_WORDS, OnChoiceWords) ON_BN_CLICKED(IDC_CHOICE_NUMBERS, OnChoiceNumbers) ON_BN_CLICKED(IDC_SELECT_WORDS, OnSelectWords) //}}AFX_MSG_MAP END_MESSAGE_MAP()

///////////////////////////////////////////////////////////////////////////// // CInGodsTimeDlg message handlers

BOOL CInGodsTimeDlg::OnInitDialog() { CDialog::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } }

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here

    init_counter();
    m_max=1448;
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CInGodsTimeDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } }

// If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework.

void CInGodsTimeDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CInGodsTimeDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; }

// long fsize(FILE f) { long result,original=ftell(f); fseek(f,0,SEEK_END); result=ftell(f); fseek(f,original,SEEK_SET); return result; }

WORD hash_string(const char src) { BYTE_WORD sum; sum.w =0; while (src) { sum.w += ((src++)); sum.w char malloc_string(const char src) { int len=strlen(src); char result=(char )malloc(len+1); strcpy(result,src); return result; }

#define pm_numbers 0 #define pm_words 1 int pick_mode=pm_numbers;

class hash_entry { public: hash_entry next; char body; }; typedef hash_entry hash_ptr;

#define hash_table_size 4096 bool hash_initialized=false; int num_hash_entries=0; hash_ptr hash_table[hash_table_size]; int start_word,end_word; char word_list=NULL;

void generate_word_list() { int i,j=0; hash_ptr temph; if (word_list) { free(word_list); } word_list=(char )malloc(sizeof(char )num_hash_entries); for (i=0;ibody; temph=temph->next; } } }

void process_word(char st) { // char src=st; int i; hash_ptr temph,temph1; // while (src) { // src=toupper(src); // src++; // } i=hash_string(st) & (hash_table_size-1); temph=hash_table[i]; while (temph) { if (!strcmp(temph->body,st)) return; temph=temph->next; } temph1=new hash_entry; temph1->body=malloc_string(st); temph1->next=hash_table[i]; hash_table[i]=temph1; num_hash_entries++; }

void process_file(char buf,int len) { int i,j; if (!hash_initialized) { for (i=0;i='A' && buf[i]='a' && buf[i]='0' && buf[i]' || buf[i]=='_' || buf[i]=='\'') && i='A' && buf[i]='a' && buf[i]='0' && buf[i]' || buf[i]=='_' || buf[i]=='\'')) { buf[i]=0; break; } else i++; if (jvoid CInGodsTimeDlg::OnSelectWords() { int file_size; FILE in_file; char buf,cur_dir[MAX_PATH+32]; CFileDialog d(TRUE,"Txt","",OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, "Text Files (.Txt)|.Txt|All Files (.)|.||");

  GetCurrentDirectory(MAX_PATH,cur_dir);
  strcat(cur_dir,"\\*.TXT");
  d.GetOFN().lpstrFile=cur_dir;

  if (d.DoModal()==IDCANCEL)
    return;
  in_file=fopen(d.GetPathName(),"rb");

  UpdateData();
/* if (m_main.GetLength()) m_main+="\r\n\r\n"; m_main+=d.GetPathName(); m_main+="\r\n\r\n"; / UpdateData(FALSE);

  file_size=fsize(in_file);
  buf=(char *) malloc(fsize(in_file)+1);
  fread(buf,file_size,1,in_file);
  buf[file_size]=0;
  fclose(in_file);
  process_file(buf,file_size);
  free(buf);
  OnChoiceWords();
}

#define DIVISOR 1

void CInGodsTimeDlg::OnStop() { int l,col; LARGE_INTEGER count; // char buf[128];

  QueryPerformanceCounter(&count);
  UpdateData();
  switch (pick_mode) {
    case pm_numbers:
        m_num=(count.LowPart/DIVISOR)% m_max+1;
      break;
    case pm_words:
      if (num_hash_entries) {
            l=m_main.GetLength();
            col=l-1;
            while (col>0  && l!=0)
            if (m_main.GetAt(col)==13)
              break;
            else
              col--;
            if (l-col>55)
              m_main+="\r\n";
// sprintf(buf,"\r\n%010u ",count.LowPart/DIVISOR); // m_main+=buf; m_num=(count.LowPart/DIVISOR)% num_hash_entries; m_main+=word_list[m_num]; m_main+=" "; m_num=1; } break; } UpdateData(FALSE); }

void CInGodsTimeDlg::OnChoiceWords() { UpdateData(); pick_mode=pm_words; m_num=1; UpdateData(FALSE); }

void CInGodsTimeDlg::OnChoiceNumbers() { UpdateData(); pick_mode=pm_numbers; m_num=1; UpdateData(FALSE); }

Re: Ask HN: Take down my reverse-engineered Snapchat lib because they asked?

#136

Earlier quoted context omitted.

If I complied with every request like this, I wouldn't have made a single successful website. You shouldn't be so afraid to stand up for yourself. Entrepreneurs need to have thick skin and not buckle under every little bit of pressure.

Every website you made received requests like these? If you don't mind me asking, what kind of websites do you make? I've never received requests like these myself.

I have been asked to remove profiles, data, images, features, the entire website, the domain, links, the list goes on. Sometimes just a few, sometimes an amount that would cripple the business. Most of the claims are overreaching bullying or ignorance. Sometimes they are just completely out of their mind nut jobs that don't understand how stuff works.

Re: Ask HN: Take down my reverse-engineered Snapchat lib because they asked?

#137
post #69

I hate to play devil's advocate here (especially since I already have a post here) but I had a thought. For Snapchat some of the biggest selling points are the self destruct abilities of the media sent. So an unauthorized client puts a stake trough the heart of that claim (and the company). I see why they may be worried, but I think that they should have communicated their concerns more clearly and pleading, and not…

If they rely on the client to determine when things are deleted from their service, they're doing something wrong. Never trust the client software! The only thing a rogue client should be able to do is surreptitiously send a copy of your pictures Somewhere Else (for storage). All the pictures sent to Snapchat should get deleted on schedule, regardless of who or what sent the pictures.

If they allow the client to display the image, they allow the client to do anything with the image. Of course they stop serving images on a particular schedule. (I sort of doubt they stick with that same schedule in deleting from their central storage, but whatever.) Since Snaphax is completely client-side, however, their server policies are irrelevant.
Post reply on HN